{"openapi":"3.1.0","info":{"title":"Saldenwerk API","version":"1.0.0","description":"Die versionierte Saldenwerk REST-API. Die aktuelle Version ist read-only und umfasst den Health-Check sowie das Lesen von Kunden. Ein Administrator erstellt organisationsgebundene API-Zugänge in den Saldenwerk-Einstellungen. Weitere Ressourcen werden erst veröffentlicht, wenn Route, Datenvertrag, Berechtigungen und Dokumentation gemeinsam verifiziert sind.","contact":{"name":"Saldenwerk Support","url":"/docs"}},"servers":[{"url":"/api/v1","description":"Aktuelle Saldenwerk-Installation"}],"tags":[{"name":"System","description":"Verfügbarkeit und Versionsinformationen."},{"name":"Kunden","description":"Kunden der Organisation lesen, an die der API-Zugang gebunden ist."}],"paths":{"/health":{"get":{"operationId":"getHealth","summary":"API-Status prüfen","description":"Liefert den Status der versionierten API-Fassade. Dieser Endpunkt benötigt keine Authentifizierung.","tags":["System"],"responses":{"200":{"description":"Die API ist erreichbar.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"},"example":{"data":{"status":"ok","service":"saldenwerk-api","version":"v1","timestamp":"2026-08-02T12:00:00.000Z"}}}}}}}},"/customers":{"get":{"operationId":"listCustomers","summary":"Kunden auflisten","description":"Liefert Kunden der Organisation, an die der verwendete API-Zugang gebunden ist. Die Liste ist nach Erstellungszeitpunkt absteigend sortiert.","tags":["Kunden"],"security":[{"ApiTokenAuth":[]}],"parameters":[{"name":"limit","in":"query","description":"Maximale Anzahl der Ergebnisse.","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"search","in":"query","description":"Optionaler Teiltextfilter auf den Firmennamen.","required":false,"schema":{"type":"string","minLength":1,"maxLength":100}}],"responses":{"200":{"description":"Kundenliste.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerListResponse"},"example":{"data":[{"id":"00000000-0000-0000-0000-000000000001","createdAt":"2026-08-02T10:00:00.000Z","updatedAt":"2026-08-02T10:00:00.000Z","companyName":"Beispiel GmbH","contactPerson":"Max Mustermann","street":"Musterstraße 1","postalCode":"10115","city":"Berlin","country":"DE","email":"max@example.com","phone":null,"taxId":null,"vatId":"DE123456789","isActive":true}],"meta":{"count":1,"limit":50,"hasMore":false}}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/customers/{id}":{"get":{"operationId":"getCustomer","summary":"Kunden nach ID abrufen","description":"Liefert einen Kunden aus der Organisation, an die der verwendete API-Zugang gebunden ist.","tags":["Kunden"],"security":[{"ApiTokenAuth":[]}],"parameters":[{"name":"id","in":"path","description":"UUID des Kunden.","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Kunde.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerResponse"}}}},"400":{"$ref":"#/components/responses/InvalidRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalError"}}}}},"components":{"securitySchemes":{"ApiTokenAuth":{"type":"http","scheme":"bearer","bearerFormat":"Saldenwerk API Token","description":"Ein organisationsgebundener Saldenwerk API-Token aus Einstellungen > API-Zugänge. Im Request als `Authorization: Bearer sw_live_…` senden. Den vollständigen Token niemals in Quellcode, Logs, URLs oder Tickets speichern."}},"schemas":{"HealthResponse":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["status","service","version","timestamp"],"properties":{"status":{"type":"string","const":"ok"},"service":{"type":"string","example":"saldenwerk-api"},"version":{"type":"string","example":"v1"},"timestamp":{"type":"string","format":"date-time"}}}}},"Customer":{"type":"object","required":["id","createdAt","updatedAt","companyName","street","postalCode","city","country","isActive"],"properties":{"id":{"type":"string","format":"uuid"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"companyName":{"type":"string"},"contactPerson":{"type":["string","null"]},"street":{"type":"string"},"postalCode":{"type":"string"},"city":{"type":"string"},"country":{"type":"string","minLength":2,"maxLength":2,"example":"DE"},"email":{"type":["string","null"],"format":"email"},"phone":{"type":["string","null"]},"taxId":{"type":["string","null"]},"vatId":{"type":["string","null"]},"isActive":{"type":"boolean"}}},"CustomerListResponse":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Customer"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}},"CustomerResponse":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Customer"}}},"ListMeta":{"type":"object","required":["count","limit","hasMore"],"properties":{"count":{"type":"integer","minimum":0},"limit":{"type":"integer","minimum":1,"maximum":100},"hasMore":{"type":"boolean"}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","example":"unauthorized"},"message":{"type":"string"},"requestId":{"type":"string","format":"uuid"}}}}}},"responses":{"InvalidRequest":{"description":"Die Anfrage ist ungültig.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Unauthorized":{"description":"Authentifizierung fehlt oder ist ungültig.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Forbidden":{"description":"Der Account darf die Organisation nicht lesen.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"Die Ressource wurde nicht gefunden.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"InternalError":{"description":"Unerwarteter Fehler auf Serverseite.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}