Änderungsprotokoll
Jeder Eintrag nennt das Datum der Änderung. Die Spezifikationsrevision ist das Datum des jüngsten Eintrags, der die Beschreibung der API betrifft (aktuell 2026-10-20); sie steht in der openapi.json als info.x-revision. Wie wir ankündigen und was in v1 möglich ist, steht unter Versionierung.
| Datum | Änderung |
|---|---|
| 2026-10-20 | Webhooks: drei weitere abonnierbare Ereignistypen. contract.terminated (Kündigung bestätigt, data.lease_id), invoice.cancelled (Rechnung storniert, data.invoice_id = stornierte Original-Rechnung) und damage.updated (Fallakte geändert, data.damage_id). Sie gelten nur für Webhooks, die sie ausdrücklich in events aufführen; bestehende Webhooks ändern sich nicht. damage.updated und contract.terminated können dasselbe Objekt mehrfach melden. Das enum von events und event_type wächst um drei Werte (Codegeneratoren mit geschlossenem Enum neu erzeugen); ebenso die Simulation in der Sandbox. Neu im Starterprojekt, in der Postman-Sammlung und im Webhooks-Handbuch. |
| 2026-10-15 | Sicherheitskontakt: Schwachstellen melden Sie an security@manage2hero.com; die Seiten Sicherheit & Support und Sicherheit & Bedrohungsmodell nennen den Meldeweg samt Hinweis, was eine Meldung enthalten soll und was nicht. Zusätzlich liefert der API-Host die security.txt nach RFC 9116 unter /.well-known/security.txt aus. Verhalten und Nachrichten der API ändern sich nicht. |
| 2026-10-15 | Sicherheit & Bedrohungsmodell: Die neue Seite beschreibt, was die API schützt, wer sie angreifen könnte, welche Schutzmaßnahmen dagegen stehen, welche Grenzen und Restrisiken bekannt sind (u. a. keine unabhängige Penetrationstest-Bescheinigung) und was Kunden tun sollten. Verlinkt aus Einführung, Sicherheit & Support, Webhooks-Handbuch und Fehlerkatalog. Verhalten und Nachrichten der API ändern sich nicht. |
| 2026-10-15 | Spezifikation und Doku, Konsistenz (2. externe Prüfung): Das Node.js-Beispiel des Webhooks-Handbuchs verweist zum Nachladen einer Zahlung jetzt auf GET /v1/payments/by-ids?ids=<payment_id>. Idempotenz: Die Standardregel (gleicher Schlüssel mit anderem Inhalt = 409 idempotency_conflict) ist als solche gekennzeichnet; die Ausnahme retry-failed (anderer Filter = neuer Vorgang) steht direkt daneben. POST /v1/webhooks und PATCH /v1/webhooks/{id}: events ist in der OpenAPI als uniqueItems beschrieben (Duplikate werden abgelehnt). Fehlercode payload_too_large nennt keine pauschale Größe mehr, sondern verweist auf error.details.max_bytes (je Endpunkt verschieden, z. B. 4096 beim Sammel-Replay). Seitenweise Listen: die Ausnahme GET /v1/webhooks steht schon in der allgemeinen Regel. Grenzen: Die Importgrenzen (20 neue Importe je Konto in 10 Minuten, 500 Importe je Organisation) stehen vollständig in den Tabellen. Die Retry-Beispiele der Referenz speichern den Idempotency-Key dauerhaft (Datei) und verwenden ihn bei jedem Neustart wieder. Die OpenAPI und das Webhooks-Handbuch verweisen ausdrücklich auf den Abschnitt webhooks (Hinweis für Codegeneratoren). Neu: Integrations-Checkliste im Webhooks-Handbuch. Statusseite: Die Verfügbarkeit nennt Messbeginn und gemessene Tage („gemessen seit …: X von 90 Tagen“); die Zeit vor Messbeginn ist keine Basis. Verhalten der API und Nachrichten ändern sich nicht. |
| 2026-10-15 | Änderungsabgleich für Verträge und Schäden: …/contracts/changes/cursor, …/contracts/changes, …/contracts/by-ids sowie …/damages/changes/cursor, …/damages/changes, …/damages/by-ids (Scopes contracts:read und damages:read). Der Strom meldet auch gelöschte oder zum Löschen vorgemerkte Verträge, zurückgesetzte Gegenzeichnungen, gelöschte Kündigungen, Nachträge, Schaden-Dokumente und Meldungen sowie gelöschte Schäden; die Antwort von /v1/damages/by-ids hat die Listenform ohne documents. Das Starterprojekt gleicht beide Ressourcen jetzt über den Strom ab. |
| 2026-10-15 | Sandbox-Doku und Sicherheitsdurchsicht. Die Seite Sandbox (Testmodus) führt jetzt in vier Schritten zur ersten Antwort, zeigt die Antwort der Ereignis-Simulation, vergleicht Sandbox und echte Daten und erklärt die typischen Fehlerbilder (u. a. 403 sandbox_unavailable). Die Postman-Sammlung hat einen Ordner Sandbox (Testmodus) mit eigener Variable sandbox_token. Die OpenAPI verweist auf die Sandbox-Seite und nennt 403 sandbox_unavailable beim Bearer-Schema. Verhalten und Nachrichten der API ändern sich nicht. |
| 2026-10-14 | Starterprojekt zum Herunterladen: Das Webhook-Starterprojekt (Node.js, ohne Fremdabhängigkeiten, mit Signaturprüfung, Eingangstabelle, Abgleich, Simulator und den gemeinsamen Testvektoren) gibt es jetzt als ZIP ohne Anmeldung unter /downloads/manage2hero-webhook-starterprojekt.zip auf diesem Host. Der Beispielcode steht unter der MIT-Lizenz; die API selbst unterliegt den Nutzungsbedingungen. Die Nachrichten und Endpunkte der API ändern sich nicht. |
| 2026-10-14 | Spezifikation und Doku, Konsistenz (nach externer Prüfung): POST /v1/webhooks beschreibt die Antwort 200 (Wiederholung, ohne secret) getrennt von 201 (Neuanlage, secret Pflicht). Höchstspanne der Listenabrufe einheitlich als Kalendertage mit from und to (366 bei Buchungen und Zahlungseingängen, 1.831 bei Rechnungen, Mahnungen, Nettoumsatz und Vermietungsquote je Monat; to − from höchstens 365 bzw. 1.830). Beispielnachricht des Webhooks-Handbuchs mit livemode und X-M2H-Livemode. webhook_limit_reached nennt limit und used (Sandbox: nur limit). GET /v1/webhooks ohne next_cursor ausdrücklich vermerkt; Hinweis für Code-Generatoren, unbekannte Enum-Werte zu tolerieren. Das Verhalten der API ändert sich nicht. |
| 2026-10-14 | Sandbox: Webhooks und Ereignis-Simulation. Test-Tokens dürfen den Scope webhooks:manage tragen; Sandbox-Webhooks laufen über denselben Zustelldienst (Signatur, Wiederholung, Replay, nur https auf Port 443). Neu: POST /v1/sandbox/events (Scope webhooks:manage, nur Sandbox-Token, Idempotency-Key) simuliert ein Ereignis für ein Musterobjekt. Neu in JEDER Webhook-Nachricht: das Feld livemode im Körper und der Kopf X-M2H-Livemode (false für Sandbox-Ereignisse, true für alle anderen) - die Nachrichten wurden um dieses Feld erweitert, ältere Empfänger ignorieren es. Zustellungen, die schon vor Einführung des Feldes eingestellt waren, behalten ihren bisherigen Körper ohne livemode (ein fehlendes Feld gilt als true). Höchstens 3 Webhooks je Sandbox; Zustellungen der Sandbox werden nach 7 Tagen gelöscht. |
| 2026-10-14 | Sandbox: weitere Musterdaten. Eine neue oder zurückgesetzte Sandbox enthält zusätzlich Konditionen, drei Monatsmieten je Vertrag (drei Mieter im Rückstand), 27 Zahlungseingänge, drei Rechnungen, drei Mahnungen, sechs Zähler mit Zählerständen, Schäden, Termine, Interessenten, Dokument-Metadaten (ohne Datei) und einen E-Mail-Verlauf (nur Protokollzeilen, es wird nichts gesendet). Damit liefern auch Buchungen, Zahlungen, offene Posten, Rechnungen, Mahnungen, Zähler, Schäden, Termine, Interessenten, Dokumente und E-Mails Beispieldaten. Die Nachrichten und Endpunkte der API ändern sich nicht. |
| 2026-10-13 | Sandbox (Testmodus): Unter Administration → API-Zugänge → Sandbox legt ein Mandant eine eigene Test-Organisation mit erfundenen Musterdaten an und erzeugt Test-Tokens (Präfix m2h_test_). Dieselbe Adresse wie für echte Tokens; Test-Tokens sehen nur die Musterdaten, echte Tokens nie die Sandbox. Jede Antwort auf ein Test-Token trägt den Kopf X-M2H-Sandbox: true. Engere Grenzen (60 lesende, 10 schreibende Aufrufe je Minute und Token, 500 schreibende Aufrufe je Tag), keine E-Mails, Webhooks noch nicht verfügbar. Die Nachrichten und Endpunkte der API ändern sich nicht. |
| 2026-10-13 | Statusseite: Die neue Seite Status (/docs/status) zeigt öffentlich und ohne Anmeldung, ob die API und die Webhook-Zustellung gerade funktionieren – je Komponente der Zustand, die Verfügbarkeit der letzten 30 und 90 Tage, Vorfälle mit Beginn, Ende und Kurztext sowie wenige Kennzahlen (Zustellverzug, Zustell-Latenz, Antwortzeit der API), nur aggregiert und ohne Angaben zu einzelnen Kunden. Die Beschreibung (info der OpenAPI) verweist auf die Seite; die Nachrichten und Endpunkte ändern sich nicht. |
| 2026-10-13 | Webhooks: Pausieren statt Verwerfen. Beim Abschalten eines Webhooks werden offene Zustellungen pausiert (neuer Status paused, auch als Filter im Zustellverlauf) statt verworfen; solange die API freigeschaltet ist, werden neue Ereignisse weiter aufgezeichnet (bis zu 10.000 je Webhook, höchstens 29 Tage). Nach PATCH active: true nimmt der Server sie von selbst wieder auf (je Minute höchstens 60 je Webhook, älteste zuerst, gleiche Ereignis-Id); PATCH-Feld paused_deliveries (resume | discard, nur mit active: true). Neue Felder am Webhook: pending_deliveries, paused_deliveries, recording_gap (Lücke der Aufzeichnung, Abgleich über updated_since); neuer Grund paused bei delivery_not_replayable. Die Zustellung mit dem sechsten Fehlversuch bleibt failed. Die Nachrichten selbst ändern sich nicht. |
| 2026-10-12 | Spezifikation und Doku: Die OpenAPI beschreibt jetzt die Webhook-Nachrichten formal (Abschnitt webhooks, OpenAPI 3.1) für die sieben Ereignisse und webhook.test. Alle Endpunkte registrieren die Antwort 500 internal_error; error.details ist typisiert und je Endpunkt beschrieben. Fehlercodes haben eine Handlungsanweisung. Neu bzw. überarbeitet: Schnellstart mit Webhook-Pfad, Idempotenz-Ablauf samt Tabelle je Endpunkt, Versionierung und Auslaufen, Sonderfälle der Rate-Limits, Hinweise zu Listenabruf und Änderungsabgleich. Neues Feld info.x-revision in der openapi.json. Korrigiert: Die Testzustellung ist nur so lange dieselbe, wie sie im Zustellverlauf steht (30 Tage). |
| 2026-10-12 | Webhooks: Zustellungen erneut senden (Replay). POST /v1/webhooks/{id}/deliveries/{delivery_id}/retry stellt eine fehlgeschlagene (failed) oder verworfene (abandoned) Zustellung erneut ein, POST /v1/webhooks/{id}/deliveries/retry-failed bis zu 100 auf einmal (Filter nach Zeitraum, Status und Ereignistyp; Scope webhooks:manage, Idempotency-Key). Dieselbe Ereignis-Id, neuer Zeitstempel und neue Signatur; höchstens 1000 je Webhook und Stunde. Neues Feld replay_count im Zustellverlauf, neuer Fehlercode delivery_not_replayable (409). |
| 2026-10-10 | Mieter-Zeitleiste: GET /v1/tenants/{id}/timeline (Scope timeline:read) mit Ereignissen aus E-Mails, Mahnungen, Zahlungen, Dokumenten und Vertrag. Eine Quelle erscheint nur, wenn das Token zusätzlich ihren Lese-Scope hat; timeline:read allein liefert eine leere Liste. |
| 2026-10-10 | Webhooks: GET/POST /v1/webhooks, GET/PATCH/DELETE /v1/webhooks/{id}, rotate-secret, test und Zustellverlauf (Scope webhooks:manage). Ereignisse payment.received, dunning.sent, contract.signed, invoice.created, document.created, email.sent und damage.created; signierte, dünne Nachrichten mit Wiederholungen. Neue Fehlercodes webhook_url_invalid und webhook_limit_reached. Neu: das Webhooks-Handbuch mit Signatur-Beispielen. |
| 2026-10-10 | Verträge: GET /v1/contracts und /v1/contracts/{id} (Scope contracts:read) mit Unterschriftsstand, Kündigungen und Nachträgen; CSV und Excel möglich. |
| 2026-10-10 | Einheiten und Garagen: GET /v1/units und /v1/units/{id} (Scope units:read) mit Status, aktuellem Vertrag, Mieter und Grundmiete. |
| 2026-10-10 | Nebenkosten und Zähler: GET /v1/utility/statements, /v1/meters, /v1/meters/{id}/readings (Scope utility:read) und POST /v1/meters/{id}/readings zum Eintragen eines Zählerstands (Scope utility:write, Idempotency-Key, Plausibilitätsprüfung). |
| 2026-10-10 | DATEV: POST /v1/datev/exports, GET /v1/datev/exports, GET /v1/datev/exports/{id} und POST /v1/datev/exports/{id}/download-link (Scope datev:export); Link 5 Minuten gültig, Datei 24 Stunden abrufbar, höchstens 30 neue Exporte je Organisation und Stunde. Neuer Fehlercode export_not_ready. |
| 2026-10-10 | Handwerker: GET /v1/contractors und GET /v1/contractor-orders (Scope contractors:read); CSV und Excel möglich. |
| 2026-10-10 | Schäden: GET /v1/damages und /v1/damages/{id} (Scope damages:read) sowie POST /v1/damages und PATCH /v1/damages/{id}/status (Scope damages:write, Idempotency-Key). |
| 2026-10-10 | Termine: GET /v1/appointments und /v1/appointments/{id} (Scope appointments:read, mit upcoming=true) sowie POST /v1/appointments (Scope appointments:write, Idempotency-Key; keine E-Mails und Benachrichtigungen). Neuer Fehlercode appointment_conflict. |
| 2026-10-10 | Interessenten: GET /v1/prospects, /v1/prospects/{id} und /v1/waitlist (Scope prospects:read, ohne Kontaktdaten) sowie POST /v1/prospects (Scope prospects:write; 30 Anfragen je Token und Stunde, 5 je E-Mail-Adresse in 24 Stunden). |
| 2026-10-09 | E-Mails an Mieter: GET /v1/emails, /v1/emails/{id} und Änderungsabgleich (Scope emails:read; Volltext nur mit dem Zusatz-Scope emails:read_body). 38 freigegebene Vorlagen, ohne Empfängeradresse und ohne Zugangsdaten-Mails. |
| 2026-10-09 | Zugriffsprotokoll: GET /v1/usage (Scope usage:read) mit Filtern nach Token, Status und Pfad; 90 Tage Aufbewahrung. |
| 2026-10-09 | CSV und Excel: Buchungen, Rechnungen, Zahlungseingänge, Mahnungen, offene Posten und E-Mails als Datei über ?format=csv|xlsx; Trennzeichen über delimiter; Cursor im Kopf X-Next-Cursor; Fehlercode unsupported_format. |
| 2026-10-09 | Gemeinsamer Zeitfilter für die neuen Listen: period, date oder from/to; ohne Angabe die letzten 30 Tage. Neue Fehlercodes period_conflict und range_invalid. |
| 2026-10-09 | Dokumente: GET /v1/documents, /v1/documents/{id}, Änderungsabgleich und kurzlebige Download-Links (Scopes documents:read und documents:download). Ein Token darf jetzt bis zu 40 Scopes tragen. |
| 2026-10-07 | Import abbrechen: DELETE /v1/tenant-imports/{id} (Scope tenants:import); neuer Fehlercode session_has_transferred_records (409). Die Übernahme meldet bei already_transferred jetzt auch contract_number; ihr Body ist auf 64 KB begrenzt (413 payload_too_large, vorher wurde bis 1 MB angenommen). |
| 2026-10-07 | Einheitliche, lesbare Fehler: error.details ordnet jedem Feld feste Codes zu (required, invalid_uuid, unknown_parameter, too_many_ids …), error.message nennt das erste Problem; unbekannte Parameter und Felder werden benannt. from nach to meldet überall range_invalid (details.to = before_from). Ungültige Kennung im Pfad: 400 statt 404. Unbekannte Adressen: 404 route_not_found im Standardformat mit request_id. Neuer Fehlercode invalid_authorization_scheme (401). Kopf X-RateLimit-Reset neu; X-RateLimit-* jetzt auf allen Antworten mit bekanntem Token. GET /v1/openapi.json wie /openapi.json; servers der OpenAPI nennt die Hosts der Umgebung. Cursor des Änderungsabgleichs gelten nur für ihre Ressource. |
| 2026-09-29 | Änderungsabgleich für Buchungen, Rechnungen, Zahlungseingänge und Mahnungen: …/changes/cursor, …/changes und …/by-ids; neuer Fehlercode cursor_expired (410). |
| 2026-09-29 | Abrufprotokoll: jeder Abruf wird 90 Tage protokolliert, abgelehnte Anmeldungen mit bekannter Token-Kennung eingeschlossen; Verlauf je Token in der Verwaltung. |
| 2026-09-28 | Rechnungen (GET /v1/invoices, Scope invoices:read) und Zahlungseingänge (GET /v1/payments, Scope payments:read). Bankdaten und Verwendungszweck der Zahlenden nur mit dem Zusatz-Scope payments:read_counterparty. |
| 2026-09-28 | Offene Posten (GET /v1/open-items, /v1/open-items/summary, Scope open_items:read) und Mahnwesen lesend (GET /v1/dunning/leases, /v1/dunning/notices, Scope dunning:read). |
| 2026-09-28 | Finanzen: Buchungsjournal (GET /v1/bookings) und Nettoumsatz (GET /v1/revenue), Scope bookings:read. Ein Mieter, auch ohne laufenden Vertrag (GET /v1/tenants/{id}, Scope tenants:read). |
| 2026-09-28 | Vermietungsquote: Verlauf je Tag oder Monat (GET /v1/occupancy/history) und Aufteilung nach Garagentyp (?group_by=storage_type); neuer Fehlercode range_too_large. |
| 2026-09-25 | Übernahme per API: POST /v1/tenant-imports/{id}/commit (Scope tenants:import_commit). Eigene Grenzen für Importe; Tokens wirken nur, solange der Ersteller das Recht API-Zugang hat. |
| 2026-09-25 | Dokumentation zusätzlich auf Englisch (/docs/en); OpenAPI auf Englisch über ?lang=en. |
| 2026-09-24 | Mieterimport: POST /v1/tenant-imports und GET /v1/tenant-imports/{id} (Scope tenants:import). |
| 2026-09-24 | v1 veröffentlicht (Pilot): Garagenparks, Vermietungsquote, aktuelle Mieter. |