{"openapi":"3.1.0","info":{"title":"Zähler-Portal API v1","version":"1.0.0","summary":"Lese- und Schreibzugang für Netze, Anlagen, Messwerte, Berichte und Verwaltung.","description":"Jedes Token besitzt eine Vorgangsklasse (lesend < stammdaten < voll) und kann an höchstens ein Netz gebunden sein. Eine Netzbindung schränkt alle Antworten und Schreibvorgänge auf dieses Netz ein; sie erteilt keine zusätzlichen Rechte. Schreibende Endpunkte sind ausdrücklich dokumentiert und verlangen zusätzlich die Berechtigungen des Tokeninhabers. Jede Antwort bleibt auf den Umfang beschränkt, den derselbe Mensch in der Oberfläche verwenden darf."},"servers":[{"url":"https://zaehler-portal.net","description":"Produktion"}],"security":[{"apiToken":[]}],"tags":[{"name":"Token","description":"Auskunft über den Zugang selbst."},{"name":"Netze"},{"name":"Anlagen"},{"name":"Berichte","description":"Berichtsaufträge des eigenen Kontos."}],"paths":{"/api/v1/me":{"get":{"tags":["Token"],"operationId":"eigeneKennung","summary":"Wer bin ich, und womit frage ich?","description":"Liefert ausschließlich die Identität des Menschen, dem das Token gehört, und die Kennzeichen des Tokens. Der übliche erste Aufruf eines neu eingerichteten Zugangs.","responses":{"200":{"description":"Der Zugang trägt.","content":{"application/json":{"schema":{"type":"object","required":["nutzer","token"],"properties":{"nutzer":{"type":"object","required":["id","email","name"],"properties":{"id":{"type":"integer"},"email":{"type":["string","null"]},"name":{"type":["string","null"]}}},"token":{"type":"object","required":["id","nurLesend","vorgangsklasse","netzId"],"properties":{"id":{"type":"integer"},"nurLesend":{"type":"boolean","description":"Ein Informationsfeld, das aus vorgangsklasse abgeleitet wird. Für Zugriffsentscheidungen muss ein Klient vorgangsklasse verwenden."},"vorgangsklasse":{"type":"string","enum":["lesend","stammdaten","voll"],"description":"Der Zuschnitt DIESES Tokens. Ordnung: lesend < stammdaten < voll. Sie wirkt ausschließlich einschränkend - ein voll-Token kann nie mehr, als sein Mensch im Portal darf."},"netzId":{"type":["integer","null"],"description":"Das Netz, an das dieses Token gebunden ist. null heißt ALLE Netze, die dieser Mensch sehen darf - null ist hier also der WEITE Wert."}}}}}}}},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/Tokenzuschnitt"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}},"/api/v1/networks":{"get":{"tags":["Netze"],"operationId":"netzeAuflisten","summary":"Die Netze, die dieser Mensch sehen darf.","description":"Liefert dieselben sichtbaren Netze wie die Netzübersicht der Oberfläche. Die dort angezeigten Kennzahlen sind nicht Teil dieser Antwort.","responses":{"200":{"description":"Die sichtbaren Netze. Eine leere Liste heißt: keines sichtbar.","content":{"application/json":{"schema":{"type":"object","required":["netze"],"properties":{"netze":{"type":"array","items":{"type":"object","required":["id","slug","name","beschreibung"],"properties":{"id":{"type":"integer"},"slug":{"type":"string"},"name":{"type":"string"},"beschreibung":{"type":["string","null"]}}}}}}}}},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/Tokenzuschnitt"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}},"/api/v1/networks/{networkId}/data-act-export":{"get":{"tags":["Netze"],"operationId":"dataActMandantenexportAbrufen","summary":"Vollständigen Data-Act-Mandantenexport eines Netzes abrufen.","description":"Liefert den vollständigen geprüften ZIP64-Mandantenexport des Netzes. Zulässig sind nur aktive Lesetoken, die exakt an das Netz im Pfad gebunden sind, sowie aktive Tokeninhaber mit network.manage UND billing.manage an diesem Netz. Token, Konto, exakte Netzbindung und beide Rechte werden zu Beginn und unmittelbar vor Bereitstellung des fertigen Archivs erneut geprüft. Ungebundene Tokens sind für diesen Endpunkt nicht zulässig.","x-mcp-werkzeug":false,"x-mcp-begruendung":"Der binäre, lang laufende ZIP-Gesamtexport ist nur für direkten API-Abruf bestimmt.","security":[{"apiToken":[]}],"parameters":[{"$ref":"#/components/parameters/networkId"}],"responses":{"200":{"description":"Gestreamtes ZIP64-Archiv mit Manifest und SHA-256-Prüfsummen.","headers":{"Content-Disposition":{"description":"Technischer ASCII-Dateiname des Archivs.","schema":{"type":"string"}},"Cache-Control":{"description":"private, no-store","schema":{"type":"string","const":"private, no-store"}},"X-Content-Type-Options":{"description":"Verhindert Medientyp-Raten.","schema":{"type":"string","const":"nosniff"}}},"content":{"application/zip":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Der Token fehlt, ist unbekannt, abgelaufen oder widerrufen oder das zugehörige Konto ist gesperrt.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Die Netz-ID ist syntaktisch ungültig, der Token ist nicht exakt an das Netz gebunden, seine Klasse genügt nicht, das Netz ist unbekannt oder network.manage beziehungsweise billing.manage fehlt.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Der Export läuft bereits, die Quelle ist nicht sauber abgrenzbar oder sie hat sich während des Exports geändert.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Eine vorgelagerte IP- oder Token-/Scope-Ratenbegrenzung ist erreicht.","headers":{"Retry-After":{"description":"Wartezeit bis zum nächsten Versuch in Sekunden, sofern der Rücksetzzeitpunkt bekannt ist; bei einer Infrastrukturstörung ohne bekannte Frist fehlt der Kopf.","schema":{"type":"integer","minimum":1}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Pflichtaudit, Exportquelle oder Abschlussprüfung ist nicht verfügbar; ebenso Laufzeitabbruch oder eine sonstige ausfallsichere Exportstörung.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/v1/networks/{networkId}/plants":{"get":{"tags":["Anlagen"],"operationId":"anlagenAuflisten","summary":"Die Anlagen eines Netzes, so wie die Oberfläche sie listet.","description":"Netzweit Berechtigte sehen das logische Inventar, anlagengebundene Aufrufer nur ihre Anlagen. Kennzahlen einer nur noch historisch berechtigten Anlage sind maskiert; ihre hinterlegte Identität bleibt sichtbar.\n\nEin Netz, das der Aufrufer nicht sehen darf, beantwortet dieser Endpunkt mit einer leeren Liste - genau wie ein Netz ohne Anlagen und wie eine Kennung, die es nicht gibt. Dadurch lässt sich die Existenz eines nicht sichtbaren Netzes nicht aus der Antwort ableiten.","parameters":[{"$ref":"#/components/parameters/networkId"}],"responses":{"200":{"description":"Die sichtbaren Anlagen.","content":{"application/json":{"schema":{"type":"object","required":["anlagen"],"properties":{"anlagen":{"type":"array","items":{"$ref":"#/components/schemas/Anlage"}}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/Tokenzuschnitt"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}},"/api/v1/networks/{networkId}/plants/{memberNr}":{"get":{"tags":["Anlagen"],"operationId":"anlageLesen","summary":"Eine Anlage.","description":"Liefert genau eine Anlage mit derselben Zusammensetzung und Maskierung wie die Anlagenliste.\n\nAbwesenheit und Abweisung ergeben dieselbe Antwort (403 mit kind=kein-zugriff). Es gibt kein 404, damit sich durch das Ausprobieren von Kennungen nicht erkennen lässt, ob eine Anlage existiert.","parameters":[{"$ref":"#/components/parameters/networkId"},{"$ref":"#/components/parameters/memberNr"}],"responses":{"200":{"description":"Die Anlage.","content":{"application/json":{"schema":{"type":"object","required":["anlage"],"properties":{"anlage":{"$ref":"#/components/schemas/Anlage"}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/KeinZugriff"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}},"/api/v1/networks/{networkId}/plants/{memberNr}/readings":{"get":{"tags":["Anlagen"],"operationId":"messwerteLesen","summary":"Messwerte einer Anlage in einem Zeitraum.","description":"Ohne Angabe gilt das Vorgabefenster der Oberfläche: die letzten 30 Tage.\n\nDer angefragte Zeitraum wird auf das zeitliche Zugriffsfenster der Bindung begrenzt. Ein neuer Mieter kann über frei gewählte Grenzen nicht die Historie seines Vormieters lesen. Überlappen Zeitraum und Fenster nicht, ist die Antwort leer und kein Fehler. Das Feld zeitraum nennt die tatsächlich verwendeten Grenzen.\n\nDie Summe weist ihre Vorbehalte mit istGeschaetzt, unerklaerterSprung und fensteranfangsLuecke aus.","parameters":[{"$ref":"#/components/parameters/networkId"},{"$ref":"#/components/parameters/memberNr"},{"name":"von","in":"query","required":false,"description":"Beginn, ISO-8601. Jahr zwischen 2000 und 2100.","schema":{"type":"string","format":"date-time"}},{"name":"bis","in":"query","required":false,"description":"Ende, ISO-8601. Jahr zwischen 2000 und 2100.","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Messwerte und Summe.","content":{"application/json":{"schema":{"type":"object","required":["zeitraum","messwerte","summe"],"properties":{"zeitraum":{"type":"object","required":["von","bis"],"properties":{"von":{"type":"string","format":"date-time"},"bis":{"type":"string","format":"date-time"}}},"messwerte":{"type":"array","items":{"$ref":"#/components/schemas/Messwert"}},"summe":{"$ref":"#/components/schemas/Summe"}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/KeinZugriff"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}},"/api/v1/networks/{networkId}/plants/{memberNr}/group":{"get":{"tags":["Anlagen"],"operationId":"zaehlergruppeLesen","summary":"Die sichtbare Zählergruppe einer Anlage.","description":"Haupt- und Unterzähler an derselben Busadresse - eingeschränkt auf das, was der Aufrufer lesen darf.\n\nÜber nicht sichtbare Mitglieder enthält die Antwort weder Anzahl noch Hinweis. gruppe=null bedeutet daher entweder, dass keine Gruppe vorhanden ist, oder dass kein Mitglied einer vorhandenen Gruppe sichtbar ist. Diese Fälle sind an der Antwort nicht unterscheidbar.\n\neindeutigerHauptzaehler=null bedeutet, dass der Hauptzähler mehrdeutig, nicht vorhanden oder nicht sichtbar ist.\n\nAlle Kennungen sind logisch: Bei einem umgeleiteten Geschwister wird der Alias im Zielnetz ausgegeben, nie die physische Nummer des Quellnetzes.\n\nEine Störung ergibt keine leere Gruppe, sondern den Status 503.","parameters":[{"$ref":"#/components/parameters/networkId"},{"$ref":"#/components/parameters/memberNr"}],"responses":{"200":{"description":"Die sichtbare Gruppe, oder null.","content":{"application/json":{"schema":{"type":"object","required":["gruppe"],"properties":{"gruppe":{"oneOf":[{"type":"null"},{"type":"object","required":["mitglieder","hauptzaehler","unterzaehler","eindeutigerHauptzaehler","gefragteAnlageIstUnterzaehler"],"properties":{"mitglieder":{"type":"array","items":{"$ref":"#/components/schemas/Gruppenmitglied"}},"hauptzaehler":{"type":"array","items":{"$ref":"#/components/schemas/Gruppenmitglied"}},"unterzaehler":{"type":"array","items":{"$ref":"#/components/schemas/Gruppenmitglied"}},"eindeutigerHauptzaehler":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Gruppenmitglied"}]},"gefragteAnlageIstUnterzaehler":{"type":"boolean"}}}]}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/KeinZugriff"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}},"/api/v1/networks/{networkId}/settings":{"put":{"tags":["Netze"],"operationId":"netzeinstellungenSchreiben","summary":"Absendersignatur und Namenszusatz eines Netzes setzen.","description":"Erfordert die Vorgangsklasse stammdaten; ein lesend-Token wird mit 403 und kind=klasse-unzureichend abgewiesen, bevor die Nutzlast verarbeitet wird. Die Netzbindung des Tokens muss die Netzkennung im Pfad abdecken. Zusätzlich ist Portalverwaltung oder network.manage für dieses Netz erforderlich.\n\nÄnderung und Prüfprotokollierung sind unteilbar und auf 10 Sekunden begrenzt: Kann der Vorgang nicht vollständig protokolliert werden, bleibt die Einstellung unverändert.\n\nEine wiederholte identische Nutzlast ändert den gespeicherten Zustand nicht, wird aber als eigener Schreibversuch protokolliert. Unbekannte Felder werden abgewiesen und nicht ignoriert.","parameters":[{"$ref":"#/components/parameters/networkId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["emailSignature","senderNamePostfix"],"additionalProperties":false,"properties":{"emailSignature":{"type":"string","maxLength":2000,"description":"Signatur unter den Mails dieses Netzes. Die leere Zeichenkette löscht sie."},"senderNamePostfix":{"type":"string","maxLength":120,"description":"Zusatz hinter dem Absendernamen. Die leere Zeichenkette löscht ihn."}}}}}},"responses":{"200":{"description":"Geschrieben; der Körper nennt den gespeicherten Stand.","content":{"application/json":{"schema":{"type":"object","required":["netzId","emailSignature","senderNamePostfix"],"properties":{"netzId":{"type":"integer"},"emailSignature":{"type":"string"},"senderNamePostfix":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/Tokenzuschnitt"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}},"/api/v1/me/preferences":{"put":{"tags":["Token"],"operationId":"eigeneEinstellungenSchreiben","summary":"Die Anzeigevorlieben des EIGENEN Kontos setzen.","description":"Erfordert die Vorgangsklasse stammdaten und ändert ausschließlich die Anzeigevorlieben des Menschen hinter dem Token. Ein Zielkonto kann nicht angegeben werden.\n\nGesendet werden nur die Schlüssel, die sich ändern sollen; alle übrigen Einstellungen bleiben unverändert. Unbekannte Schlüssel werden abgewiesen und nicht stillschweigend verworfen.\n\nsessionDuration ist die Lebensdauer der eigenen Cookie-Sitzung und wird auf den Bereich von 300 Sekunden bis zu einem Jahr begrenzt. Vorher- und Nachherwert werden protokolliert.\n\nEine wiederholte identische Nutzlast ändert den gespeicherten Zustand nicht. Die Antwort nennt nur die tatsächlich übernommenen Schlüssel.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"description":"Teilmenge der bekannten Einstellungsschlüssel. Unbekannte Schlüssel führen zu 400.","properties":{"sessionDuration":{"type":"integer","minimum":300,"maximum":31536000},"dateFormat":{"type":"string"},"defaultRange":{"type":"string"},"defaultGrouping":{"type":"string"},"csvDelimiter":{"type":"string"},"csvIncludeHeader":{"type":"boolean"},"theme":{"type":"string"},"locale":{"type":"string"},"chartType":{"type":"string"},"alignToGrouping":{"type":"boolean"},"tableColumns":{"type":"object"},"columnPresets":{"type":"object"},"overrides":{"type":"object"}}}}}},"responses":{"200":{"description":"Gespeichert.","content":{"application/json":{"schema":{"type":"object","required":["geaenderteSchluessel","sitzungsdauer"],"properties":{"geaenderteSchluessel":{"type":"array","items":{"type":"string"}},"sitzungsdauer":{"type":["integer","null"]}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/Tokenzuschnitt"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}},"/api/v1/reports":{"post":{"tags":["Berichte"],"operationId":"berichtAnlegen","summary":"Einen Berichtsauftrag des eigenen Kontos anlegen.","description":"Erfordert die Vorgangsklasse stammdaten. Der Bericht gehört immer dem Menschen hinter dem Token; ein Besitzerfeld kann nicht angegeben werden.\n\nJede angegebene Anlage muss sowohl von der Netzbindung des Tokens als auch von plant:read oder einem netzweiten Lesezugriff umfasst sein. Andernfalls wird die gesamte Anfrage mit 403 abgewiesen; Anlagen werden nicht stillschweigend aus dem Bericht entfernt.\n\nMit dem Kopf Idempotency-Key liefert eine Wiederholung dieselbe Antwort wie der erste Aufruf, ohne einen zweiten Bericht anzulegen. Ohne diesen Kopf legt jede wiederholte Anfrage einen weiteren Bericht an.\n\nUnbekannte Felder werden abgewiesen. periodCount wird auf die Obergrenze der gewählten Gruppierung begrenzt.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","sendFrequency","aggregationGrouping","periodCount","plants"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1},"sendFrequency":{"type":"string","enum":["daily","weekly","monthly","quarterly","yearly"]},"sendTime":{"type":"string","pattern":"^[0-9]{2}:[0-9]{2}$","default":"08:00"},"aggregationGrouping":{"type":"string","enum":["daily","weekly","monthly","quarterly","yearly"]},"periodCount":{"type":"integer","minimum":1},"rangeUnit":{"type":["string","null"]},"columns":{"type":["array","null"],"minItems":1,"items":{"type":"string"}},"includeInterpolation":{"type":"boolean","default":true},"align":{"type":"boolean","default":false},"pdfAttachment":{"type":"boolean","default":false},"pdfMode":{"type":["string","null"],"enum":["individual","combined",null]},"plants":{"type":"array","minItems":1,"items":{"type":"object","required":["networkSlug","memberNr"],"additionalProperties":false,"properties":{"networkSlug":{"type":"string"},"memberNr":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"Angelegt; der Körper nennt die Kennung des Berichts.","content":{"application/json":{"schema":{"type":"object","required":["bericht"],"properties":{"bericht":{"type":"object","required":["id","name"],"properties":{"id":{"type":"integer"},"name":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/Tokenzuschnitt"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}},"/api/v1/reports/{reportId}":{"put":{"tags":["Berichte"],"operationId":"berichtAendern","summary":"Einen Berichtsauftrag des eigenen Kontos vollständig ersetzen.","description":"Erfordert die Vorgangsklasse stammdaten. Die Nutzlast muss den vollständigen Berichtsauftrag enthalten und ersetzt den bisherigen Stand vollständig.\n\nEine wiederholte identische Nutzlast ändert weder den Bericht noch seine Anlagenzuordnungen, wird aber als eigener Schreibversuch protokolliert. Das Feld isActive wird nicht unterstützt und wie jedes unbekannte Feld abgewiesen.\n\nJede angegebene Anlage muss sowohl von der Netzbindung des Tokens als auch von plant:read oder einem netzweiten Lesezugriff umfasst sein. Andernfalls wird die gesamte Anfrage mit 403 abgewiesen.\n\nEin nicht vorhandener Bericht und ein Bericht eines anderen Kontos führen beide zu 403 mit kind=kein-zugriff. Änderung und Prüfprotokollierung sind unteilbar und auf 15 Sekunden begrenzt; kann der Vorgang nicht vollständig protokolliert werden, bleibt der Bericht unverändert.\n\nUnbekannte Felder werden abgewiesen. periodCount wird auf die Obergrenze der gewählten Gruppierung begrenzt.","parameters":[{"name":"reportId","in":"path","required":true,"description":"Kennung des Berichtsauftrags, in vollständiger Ziffernform.","schema":{"type":"integer","minimum":1}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","sendFrequency","aggregationGrouping","periodCount","plants"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1},"sendFrequency":{"type":"string","enum":["daily","weekly","monthly","quarterly","yearly"]},"sendTime":{"type":"string","pattern":"^[0-9]{2}:[0-9]{2}$","default":"08:00"},"aggregationGrouping":{"type":"string","enum":["daily","weekly","monthly","quarterly","yearly"]},"periodCount":{"type":"integer","minimum":1},"rangeUnit":{"type":["string","null"]},"columns":{"type":["array","null"],"minItems":1,"items":{"type":"string"}},"includeInterpolation":{"type":"boolean","default":true},"align":{"type":"boolean","default":false},"pdfAttachment":{"type":"boolean","default":false},"pdfMode":{"type":["string","null"],"enum":["individual","combined",null]},"plants":{"type":"array","minItems":1,"items":{"type":"object","required":["networkSlug","memberNr"],"additionalProperties":false,"properties":{"networkSlug":{"type":"string"},"memberNr":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"Ersetzt; der Körper nennt die Kennung und die tatsächlich geänderten Anlagenzuordnungen.","content":{"application/json":{"schema":{"type":"object","required":["bericht"],"properties":{"bericht":{"type":"object","required":["id","name","anlagenEntfernt","anlagenAufgenommen"],"properties":{"id":{"type":"integer"},"name":{"type":"string"},"anlagenEntfernt":{"type":"integer"},"anlagenAufgenommen":{"type":"integer"}}}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/Tokenzuschnitt"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}},"delete":{"tags":["Berichte"],"operationId":"berichtLoeschen","summary":"Einen Berichtsauftrag des eigenen Kontos löschen.","description":"Erfordert die Vorgangsklasse stammdaten. Nach erfolgreichem Löschen bleiben Name, Frequenz, Besitzer und Anlagenkennungen im Prüfprotokoll erhalten.\n\nEin zweiter Aufruf für denselben Bericht antwortet mit 403 und kind=kein-zugriff statt mit 200. Dadurch ist nicht erkennbar, ob ein Bericht bereits gelöscht wurde oder nie dem aufrufenden Konto gehörte.\n\nAlle benötigten Angaben stehen im Pfad. Eine mitgesendete Nutzlast wird weder gelesen noch beanstandet. Löschung und Prüfprotokollierung sind unteilbar und auf 10 Sekunden begrenzt; kann der Vorgang nicht vollständig protokolliert werden, bleibt der Bericht erhalten.","parameters":[{"name":"reportId","in":"path","required":true,"description":"Kennung des Berichtsauftrags, in vollständiger Ziffernform.","schema":{"type":"integer","minimum":1}}],"responses":{"200":{"description":"Gelöscht; der Körper nennt Kennung, Namen und die Zahl der entfernten Anlagenzuordnungen.","content":{"application/json":{"schema":{"type":"object","required":["bericht"],"properties":{"bericht":{"type":"object","required":["id","name","anlagenMitGeloescht"],"properties":{"id":{"type":"integer"},"name":{"type":"string"},"anlagenMitGeloescht":{"type":"integer"}}}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/Tokenzuschnitt"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}},"/api/v1/system/column-presets":{"put":{"tags":["System"],"operationId":"spaltenvorgabenSchreiben","summary":"Die systemweiten Spaltenvorgaben setzen.","description":"Erfordert die Vorgangsklasse stammdaten und portal.manage. Der Endpunkt setzt die Vorauswahl der Tabellenspalten für das gesamte Portal, global und je Netz. Netzgebundene Token werden mit 403 und kind=kein-zugriff abgewiesen; die übermittelte Auswahl wird nicht auf einzelne Netze gekürzt.\n\nDie vollständige Struktur mit allen fünf Gruppierungen ist erforderlich. Unbekannte Felder und nicht vorhandene Netzkennungen werden abgewiesen.\n\nEine wiederholte identische Nutzlast ändert den gespeicherten Zustand nicht, wird aber als eigener Schreibversuch mit leerer Änderungsliste protokolliert. Das Prüfprotokoll nennt nur die tatsächlich geänderten Pfade, etwa global.daily, networks.7.monthly oder includeInterpolation. Änderung und Prüfprotokollierung sind unteilbar und auf 10 Sekunden begrenzt.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["global","networks"],"additionalProperties":false,"properties":{"global":{"type":"object","required":["daily","weekly","monthly","yearly","allDays"],"additionalProperties":false,"properties":{"daily":{"$ref":"#/components/schemas/Spaltenvorgabe"},"weekly":{"$ref":"#/components/schemas/Spaltenvorgabe"},"monthly":{"$ref":"#/components/schemas/Spaltenvorgabe"},"yearly":{"$ref":"#/components/schemas/Spaltenvorgabe"},"allDays":{"$ref":"#/components/schemas/Spaltenvorgabe"}}},"networks":{"type":"object","description":"Abbildung Netzkennung (Ziffernform) -> Vorgabekarte. Eine Kennung ohne Netz wird abgewiesen.","additionalProperties":{"type":"object","required":["daily","weekly","monthly","yearly","allDays"],"additionalProperties":false,"properties":{"daily":{"$ref":"#/components/schemas/Spaltenvorgabe"},"weekly":{"$ref":"#/components/schemas/Spaltenvorgabe"},"monthly":{"$ref":"#/components/schemas/Spaltenvorgabe"},"yearly":{"$ref":"#/components/schemas/Spaltenvorgabe"},"allDays":{"$ref":"#/components/schemas/Spaltenvorgabe"}}}},"includeInterpolation":{"type":"boolean","default":true}}}}}},"responses":{"200":{"description":"Geschrieben; der Körper nennt die tatsächlich geänderten Einstellungen.","content":{"application/json":{"schema":{"type":"object","required":["spaltenvorgaben"],"properties":{"spaltenvorgaben":{"type":"object","required":["geaenderteStellen","netze"],"properties":{"geaenderteStellen":{"type":"array","items":{"type":"string"}},"netze":{"type":"integer"}}}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/Tokenzuschnitt"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}},"/api/v1/networks/{networkId}/plants/{memberNr}/access/{bindingId}":{"put":{"tags":["Anlagenberechtigungen"],"operationId":"anlagenrolleAendern","summary":"Die Rolle einer bestehenden Anlagenbindung ändern.","description":"Erfordert die Vorgangsklasse voll und plant.manage für die Anlage. Die Rolle wird als Schlüsselname angegeben. Die eigene Rolle kann nicht geändert werden; ein solcher Versuch wird mit 400 abgewiesen.\n\nDas Zeitfenster der neuen Rolle wird auf das Zugriffsfenster des vergebenden Kontos begrenzt. Das Antwortfeld fensterGeklemmt zeigt an, ob diese Begrenzung angewendet wurde.\n\nEin zweiter PUT mit derselben Rolle antwortet mit 400 und dem Hinweis, dass die Rolle bereits zugewiesen ist. Eine nicht vorhandene oder nicht zu dieser Anlage gehörende Bindung führt jeweils zu 403. Eine unbekannte und eine nicht vergebbare Rolle führen ebenfalls beide zu 403.\n\nÄnderung und Prüfprotokollierung sind unteilbar und auf 10 Sekunden begrenzt; kann der Vorgang nicht vollständig protokolliert werden, bleibt die bisherige Rolle bestehen.","parameters":[{"$ref":"#/components/parameters/networkId"},{"$ref":"#/components/parameters/memberNr"},{"$ref":"#/components/parameters/bindingId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["role"],"properties":{"role":{"type":"string","minLength":1,"description":"Der SCHLÜSSELNAME der Zielrolle (z. B. plant_viewer, plant_owner) - nicht ihre Kennung."}}}}}},"responses":{"200":{"description":"Geändert; der Körper nennt die vorherige und die neue Rolle, das begrenzte Zeitfenster und ob die Begrenzung angewendet wurde.","content":{"application/json":{"schema":{"type":"object","required":["bindung"],"properties":{"bindung":{"type":"object","required":["id","netzId","memberNr","vorherigeRolle","rolle","validFrom","validUntil","fensterGeklemmt"],"properties":{"id":{"type":"integer"},"netzId":{"type":"integer"},"memberNr":{"type":"string"},"vorherigeRolle":{"type":"string"},"rolle":{"type":"string"},"validFrom":{"type":"string","format":"date-time","nullable":true},"validUntil":{"type":"string","format":"date-time","nullable":true},"fensterGeklemmt":{"type":"boolean"}}}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/Tokenzuschnitt"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}},"delete":{"tags":["Anlagenberechtigungen"],"operationId":"anlagenrechtEntziehen","summary":"Eine bestehende Anlagenbindung entziehen.","description":"Erfordert die Vorgangsklasse voll und entzieht eine bestehende Anlagenbindung. Zielkonto, Rolle, Netz, Anlagenkennung und Zeitfenster bleiben anschließend im Prüfprotokoll erhalten. Die eigene Berechtigung kann über diesen Endpunkt nicht entzogen werden; ein solcher Versuch wird mit 400 abgewiesen.\n\nAlle benötigten Angaben stehen im Pfad. Eine mitgesendete Nutzlast wird weder gelesen noch beanstandet. Ein zweiter Aufruf antwortet mit 403 statt mit 200. Eine nicht vorhandene und eine nicht zu dieser Anlage gehörende Bindung führen ebenfalls beide zu 403.\n\nEntzug und Prüfprotokollierung sind unteilbar und auf 10 Sekunden begrenzt; kann der Vorgang nicht vollständig protokolliert werden, bleibt die Bindung bestehen.","parameters":[{"$ref":"#/components/parameters/networkId"},{"$ref":"#/components/parameters/memberNr"},{"$ref":"#/components/parameters/bindingId"}],"responses":{"200":{"description":"Entzogen; der Körper nennt Kennung, Zielkonto und die entzogene Rolle.","content":{"application/json":{"schema":{"type":"object","required":["bindung"],"properties":{"bindung":{"type":"object","required":["id","netzId","memberNr","zielUserId","rolle"],"properties":{"id":{"type":"integer"},"netzId":{"type":"integer"},"memberNr":{"type":"string"},"zielUserId":{"type":"integer"},"rolle":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/Tokenzuschnitt"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}},"/api/v1/networks/{networkId}/billing-runs":{"post":{"tags":["Abrechnung"],"operationId":"abrechnungslaufStarten","summary":"Einen Abrechnungslauf für ein Netz starten.","description":"Erfordert die Vorgangsklasse voll sowie portal.manage oder billing.manage. network.manage allein genügt nicht. Der Aufruf löst einen finanziell wirksamen Vorgang aus: Ab der Stufe dry_run entstehen Belege; in der Stufe live werden sie an das Abrechnungssystem übergeben und können anschließend nur storniert werden.\n\nDie Idempotenz gilt für Belege, nicht für einzelne Laufaufrufe. Zwei gleichzeitige Starts desselben Zeitraums werden als zwei Läufe geführt, erzeugen aber nur einen Beleg. Der zweite Lauf meldet die bereits vorhandenen Belegpositionen mit outcome=idempotent. Ein Idempotency-Key ist nicht vorgesehen; maßgeblich ist der fachliche Belegschlüssel.\n\nDie Netzkennung wird ausschließlich aus dem Pfad übernommen. Ein zusätzliches Feld networkId in der Nutzlast wird abgewiesen. coverageAcknowledged bestätigt eine unvollständige Abdeckung und wird im Prüf- und Abdeckungsprotokoll des Laufs festgehalten.\n\nEin Lauf kann Teilergebnisse enthalten. Jeder erzeugte Beleg wird zusammen mit seinem Prüfnachweis gespeichert; Start und Fehlschlag des Laufs werden gesondert protokolliert.","parameters":[{"$ref":"#/components/parameters/networkId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["periodFrom","periodTo"],"properties":{"periodFrom":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Beginn des Zeitraums, YYYY-MM-DD (UTC-Mitternacht)."},"periodTo":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Ende des Zeitraums, YYYY-MM-DD (UTC-Mitternacht)."},"coverageAcknowledged":{"type":"boolean","description":"Quittung über eine unvollständige Abdeckung. Fehlend bedeutet false."}}}}}},"responses":{"200":{"description":"Der Lauf ist durchgelaufen; der Körper nennt Stufe, Modus, Belegzahl und die AUSGÄNGE je Position. outcome=idempotent heißt: der Beleg gab es schon, es ist KEIN zweiter entstanden.","content":{"application/json":{"schema":{"type":"object","required":["lauf"],"properties":{"lauf":{"type":"object","required":["netzId","stufe","modus","blockiert","belege","ausgaenge","blocker","feststellungen"],"properties":{"netzId":{"type":"integer"},"stufe":{"type":"string","enum":["shadow","dry_run","live"]},"modus":{"type":"string"},"blockiert":{"type":"boolean"},"belege":{"type":"integer"},"ausgaenge":{"type":"object","additionalProperties":{"type":"integer"},"description":"Zählung je outcome: created, promoted, idempotent, shadow-created, error."},"blocker":{"type":"integer"},"feststellungen":{"type":"integer"}}}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/Tokenzuschnitt"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}},"/api/v1/networks/{networkId}/plants/{memberNr}/access-groups/{groupId}/members/{userId}":{"delete":{"tags":["Anlagenberechtigungen"],"operationId":"gruppenmitgliedEntfernen","summary":"Ein Konto aus einer Berechtigungsgruppe nehmen.","description":"Erfordert die Vorgangsklasse voll und nimmt ein Konto aus einer Berechtigungsgruppe. Ist die Gruppe an mehrere Anlagen gebunden, verliert das Konto die über diese Gruppe vermittelten Rechte an allen diesen Anlagen. Die Antwort nennt die Zahl als betroffeneAnlagen; das Prüfprotokoll enthält die vollständige Liste mit Zeitfenstern.\n\nErforderlich ist eine direkt zugewiesene Berechtigung plant.manage für jede Anlage der Gruppe. Eine nur über eine Gruppe vermittelte Berechtigung genügt nicht. Die eigene Mitgliedschaft darf entfernt werden.\n\nAlle benötigten Angaben stehen im Pfad. Ein zweiter Aufruf antwortet mit 403 statt mit 200. Dadurch ist nicht erkennbar, ob die Mitgliedschaft bereits entfernt wurde oder nie bestand.\n\nEntzug und Prüfprotokollierung sind unteilbar und auf 10 Sekunden begrenzt; kann der Vorgang nicht vollständig protokolliert werden, bleibt die Mitgliedschaft bestehen.","parameters":[{"$ref":"#/components/parameters/networkId"},{"$ref":"#/components/parameters/memberNr"},{"$ref":"#/components/parameters/groupId"},{"$ref":"#/components/parameters/userId"}],"responses":{"200":{"description":"Entfernt; der Körper nennt Gruppe, Zielkonto und die Zahl der wirklich betroffenen Anlagen.","content":{"application/json":{"schema":{"type":"object","required":["mitgliedschaft"],"properties":{"mitgliedschaft":{"type":"object","required":["groupId","netzId","memberNr","zielUserId","betroffeneAnlagen"],"properties":{"groupId":{"type":"integer"},"netzId":{"type":"integer"},"memberNr":{"type":"string"},"zielUserId":{"type":"integer"},"betroffeneAnlagen":{"type":"integer","description":"Zahl der Anlagen, an denen die Gruppe gebunden ist - also die wirkliche Reichweite des Entzugs."}}}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/Tokenzuschnitt"},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}},"/api/v1/impersonation":{"post":{"tags":["Uebernahme"],"operationId":"uebernahmeFreigabeEinloesen","summary":"Eine Übernahme-Freigabe einlösen und die Übernahme beginnen.","description":"Erfordert die Vorgangsklasse voll und löst eine zuvor in der Oberfläche nach erneuter Passwortprüfung erteilte Übernahme-Freigabe ein. Über diesen Endpunkt kann keine Freigabe erteilt werden. Ein Feld password oder passwort wird mit 422 abgewiesen; die Antwort nennt nur den Feldnamen, nie den Wert.\n\nDie Freigabe gilt genau einmal, für genau ein Ziel, mit genau einem Token und für fünf Minuten. Bei zwei gleichzeitigen Einlöseversuchen beginnt genau eine Übernahme; der zweite Versuch erhält 409 mit kind=freigabe-verbraucht.\n\nDas aufrufende Token bleibt dem ursprünglichen Besitzer zugeordnet. Die protokollierte Übernahme ist widerrufbar, gilt höchstens vier Stunden und endet außerdem bei Fristablauf, Sperre des Zielkontos oder Verlust der Verwaltungsberechtigung des Erteilers.\n\nMit dem Kopf Idempotency-Key liefert eine Wiederholung dieselbe erfolgreiche Antwort. Abgewiesene Anfragen werden nicht für eine spätere Wiederholung gespeichert. Es gelten 10 Einlöseversuche je 60 Sekunden und Token, unabhängig von den Grenzen der Oberfläche.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["freigabe","zielUserId"],"additionalProperties":false,"properties":{"freigabe":{"type":"string","minLength":1,"description":"Der Rohwert der Freigabe (Base64URL, 43 Zeichen aus 32 Byte Zufall)."},"zielUserId":{"type":"integer","description":"Das angegebene Ziel. Es muss dem Ziel der Freigabe entsprechen."},"anlass":{"type":["string","null"],"description":"Auf wessen Anordnung. Die Angabe wird im Prüfprotokoll und bei der Übernahme vermerkt."}}}}}},"responses":{"200":{"description":"Die Übernahme ist begonnen; der Körper nennt Kennung, Ziel und Frist.","content":{"application/json":{"schema":{"type":"object","required":["uebernahme"],"properties":{"uebernahme":{"type":"object","required":["id","zielUserId","verfaelltAt"],"properties":{"id":{"type":"integer"},"zielUserId":{"type":"integer"},"verfaelltAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"$ref":"#/components/responses/UngueltigeAnfrage"},"401":{"$ref":"#/components/responses/Tokenfehler"},"403":{"$ref":"#/components/responses/Tokenzuschnitt"},"409":{"description":"freigabe-verbraucht oder ziel-nicht-handlungsfaehig oder wird-bearbeitet oder schluessel-wiederverwendet.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"410":{"description":"freigabe-verfallen: die Freigabe ist älter als fünf Minuten.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"passwort-nicht-hier: die Nutzlast trägt ein Passwortfeld. Die Antwort nennt den Feldnamen, nie den Wert.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"$ref":"#/components/responses/Ratenbegrenzung"},"503":{"$ref":"#/components/responses/Stoerung"}}}}},"components":{"securitySchemes":{"apiToken":{"type":"http","scheme":"bearer","description":"Ein persönlicher Zugriffstoken der Form zp_pat_<Geheimteil> im Kopf Authorization: Bearer. Er hängt an einem Portal-Nutzer und trägt dessen Rechte - nie mehr. Ein Cookie wird auf diesem Weg nicht gelesen."}},"parameters":{"networkId":{"name":"networkId","in":"path","required":true,"description":"Kennung des Netzes, vollständige Ziffernform.","schema":{"type":"integer","minimum":1}},"memberNr":{"name":"memberNr","in":"path","required":true,"description":"LOGISCHE Anlagenkennung - bei einer umgeleiteten Anlage der Alias im Zielnetz. Eine Zeichenkette, keine Zahl.","schema":{"type":"string","minLength":1,"maxLength":64}},"bindingId":{"name":"bindingId","in":"path","required":true,"description":"Kennung der Anlagenbindung, in vollständiger Ziffernform. Sie stammt aus der Berechtigungsansicht der Anlage.","schema":{"type":"integer","minimum":1}},"groupId":{"name":"groupId","in":"path","required":true,"description":"Kennung der Berechtigungsgruppe, in vollständiger Ziffernform. Sie stammt aus der Gruppenansicht der Anlagenberechtigungen. NICHT zu verwechseln mit der Zählergruppe unter /group - das ist etwas völlig anderes.","schema":{"type":"integer","minimum":1}},"userId":{"name":"userId","in":"path","required":true,"description":"Kennung des Kontos, das aus der Gruppe genommen werden soll, in vollständiger Ziffernform.","schema":{"type":"integer","minimum":1}}},"schemas":{"Spaltenvorgabe":{"type":"object","required":["columns"],"additionalProperties":false,"description":"Die Spaltenauswahl einer Gruppierung. Die REIHENFOLGE ist die Spaltenreihenfolge der Tabelle und deshalb Teil des Wertes - zwei Listen mit denselben Namen in anderer Folge sind verschiedene Vorgaben.","properties":{"columns":{"type":"array","minItems":1,"items":{"type":"string","minLength":1}}}},"Anlage":{"type":"object","required":["memberNr","name","adresse","ort","plz","objektNr","zaehlerNr","verbrauch1M","verbrauch1J","letzteAblesung","letzterStandEnergie","letzterStandVolumen","status","istUnterzaehler"],"properties":{"memberNr":{"type":"string"},"name":{"type":["string","null"]},"adresse":{"type":["string","null"]},"ort":{"type":["string","null"]},"plz":{"type":["string","null"]},"objektNr":{"type":["string","null"]},"zaehlerNr":{"type":["string","null"]},"verbrauch1M":{"type":["number","null"],"description":"kWh der letzten 30 Tage. null heißt UNBEKANNT, nicht 0 - der Unterschied ist verrechnungsrelevant."},"verbrauch1J":{"type":["number","null"]},"letzteAblesung":{"type":["string","null"],"format":"date-time"},"letzterStandEnergie":{"type":["number","null"]},"letzterStandVolumen":{"type":["number","null"]},"status":{"type":"string","enum":["ok","warning","error"]},"istUnterzaehler":{"type":"boolean"}}},"Messwert":{"type":"object","required":["datum","tag","energieTag","volumenTag","energieStand","volumenStand","seriennummer","status","statusDetails","istZaehlertausch"],"properties":{"datum":{"type":"string","format":"date-time"},"tag":{"type":"string","description":"Kalendertag, yyyy-MM-dd."},"energieTag":{"type":["number","null"]},"volumenTag":{"type":["number","null"]},"energieStand":{"type":["number","null"]},"volumenStand":{"type":["number","null"]},"seriennummer":{"type":["string","null"]},"status":{"type":"string"},"statusDetails":{"type":["string","null"]},"istZaehlertausch":{"type":"boolean"}}},"Summe":{"type":"object","required":["von","bis","energie","volumen","mittelTagEnergie","mittelTagVolumen","tageMitDaten","tageOhneDaten","istGeschaetzt","schaetzgrund","unerklaerterSprung","unerklaerterSprungKwh","fensteranfangsLuecke","fensteranfangsLueckeKwh"],"properties":{"von":{"type":"string","format":"date-time"},"bis":{"type":"string","format":"date-time"},"energie":{"type":"number"},"volumen":{"type":"number"},"mittelTagEnergie":{"type":"number"},"mittelTagVolumen":{"type":"number"},"tageMitDaten":{"type":"integer"},"tageOhneDaten":{"type":"integer"},"istGeschaetzt":{"type":"boolean","description":"Die Zahl ist ein Schätzwert: es fehlt das Grenzpaar echter Ablesungen."},"schaetzgrund":{"type":["string","null"],"enum":["no-boundary","single-boundary",null]},"unerklaerterSprung":{"type":"boolean","description":"Im Fenster liegt ein Rohstand-Schritt, dessen Geräte-Identität nicht belegbar ist. Die Zahl ist fraglich."},"unerklaerterSprungKwh":{"type":["number","null"]},"fensteranfangsLuecke":{"type":"boolean","description":"Die erste Grenzablesung im Fenster liegt nach dem Fensteranfang; die Menge davor fehlt in der Zahl."},"fensteranfangsLueckeKwh":{"type":["number","null"]}}},"Gruppenmitglied":{"type":"object","required":["memberNr","name","istUnterzaehler","netzId","netzSlug","istGefragteAnlage"],"properties":{"memberNr":{"type":"string","description":"LOGISCHE Kennung."},"name":{"type":["string","null"]},"istUnterzaehler":{"type":"boolean"},"netzId":{"type":"integer"},"netzSlug":{"type":"string"},"istGefragteAnlage":{"type":"boolean"}}},"Problem":{"type":"object","description":"RFC 9457. Auf kind verzweigen, nie auf title - der Titel ist Text für Menschen.","required":["type","title","status","kind"],"properties":{"type":{"type":"string","format":"uri"},"title":{"type":"string"},"status":{"type":"integer"},"kind":{"type":"string"},"feld":{"type":"string"}}}},"responses":{"Tokenfehler":{"description":"Der Token trägt nicht. kind nennt den Grund und ist stabil: kein-token, unbekannt, widerrufen, ausserhalb-fenster, konto-gesperrt.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Tokenzuschnitt":{"description":"kind=klasse-unbekannt, klasse-unzureichend oder netz-nicht-erlaubt. Der Token ist gültig, aber sein Zuschnitt deckt diesen Vorgang nicht. klasse-unzureichend: Die Vorgangsklasse ist zu eng (Ordnung lesend < stammdaten < voll). klasse-unbekannt: Die Klasse fehlt oder ist unbekannt; der Token wird abgewiesen und nicht als lesend gedeutet. netz-nicht-erlaubt: Das Token ist an ein anderes Netz gebunden; Daten des angefragten Netzes werden nicht gelesen oder zurückgegeben. Wiederholen hilft in keinem der drei Fälle - es braucht ein Token mit passendem Zuschnitt.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"KeinZugriff":{"description":"kind=kein-zugriff. Dieselbe Antwort für 'darfst du nicht' und 'gibt es nicht', damit die Antwort keine Auskunft über nicht sichtbare Daten gibt. An denselben Pfaden können auch die unter Tokenzuschnitt beschriebenen kind-Werte auftreten. Auf kind verzweigen, nicht allein auf den Statuscode.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"UngueltigeAnfrage":{"description":"kind=ungueltige-anfrage; feld nennt den beanstandeten Parameter.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Ratenbegrenzung":{"description":"kind=ratenbegrenzung. Für alle Endpunkte gelten 60 Anfragen je Minute und Adresse sowie 10 Fehlversuche je 15 Minuten und Adresse. Für Lesezugriffe gelten zusätzlich 120 Anfragen je Minute, Token und Endpunkt. Für schreibende Endpunkte treten an die Stelle dieser Lese-Tokengrenze 10 Anfragen je Minute, Token und Scope; zusätzlich gelten 30 Anfragen je Minute und Token über alle schreibenden Scopes. Alle Grenzen melden dasselbe kind und unterscheiden sich nur im title.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Stoerung":{"description":"kind=stoerung. Eine Quelle antwortet nicht. AUSDRÜCKLICH nicht eine leere Liste: 'wir konnten nicht nachsehen' ist etwas anderes als 'es ist nichts da'. Wiederholen.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}