Stammdaten
Die Stammdaten-Endpunkte beantworten die Frage, wie du die Schlüssel in einem Fall auflöst:
Was steckt hinter locationId, caseHandler, createdBy, vehicleInsuranceId oder
legalInsuranceId? Alles unter /api/external/v1, alles mit dem Scope reference-data:read —
nur der Versicherungskatalog lässt sich mit reference-data:write auch schreiben.
Zwei Arten von Stammdaten
| Art | Beispiele | Mandantenschranke |
|---|---|---|
| Mandantengebunden | Standorte, Fallabwickler, Kolleg_innen | ja — du siehst nur den Teilbaum deines Keys |
| Plattformweit | Kfz- und Rechtsschutzversicherungen | nein — ein Katalog für alle Mandanten |
Der Unterschied ist wichtig für Schreibzugriffe: ein neuer Versicherungseintrag ist sofort für
jeden Mandanten sichtbar. Genau deshalb hängt er am eigenen, höher eingestuften Scope
reference-data:write.
Standorte
GET /api/external/v1/locations (Scope reference-data:read)
GET /api/external/v1/locations/{locationCode} (Scope reference-data:read)
Liefert den Mandanten-Root und seine Unterstandorte — jeweils Stammdaten und Adress-/ Rechtsangaben in einem Objekt:
| Feld | Inhalt |
|---|---|
locationCode | eindeutiger Code; Unterstandorte heißen partner/sub |
name, partner | Anzeigename des Standorts und seines Hauptstandorts |
mainLocation | true für den Hauptstandort (Code ohne /) |
type | LOCATION, CASE_HANDLER, APPRAISER oder ADMIN |
ownProcessingAllowed | ob der Standort Fälle selbst abwickeln darf |
company, street1, street2, buildingNo, zip, city, country | Anschrift |
email, replyToEmail | Kontakt- und Antwortadresse |
management, managementType, jurisdiction, salesTaxId | Rechtsangaben (Geschäftsführung, Registergericht, USt-IdNr.) |
Der Pfadparameter ist ein Catch-all: GET /locations/musterhaus/nord liest den Unterstandort
musterhaus/nord, ohne dass du den Schrägstrich kodieren musst.
Die Antwort enthält bewusst keine Integrations-Zugangsdaten, keine Tally-Konfiguration und keine Theme-Rohdaten — das interne Standortmodell trägt Passwörter und verlässt den Server nie.
Ein Standort außerhalb deines Mandanten und ein nicht existierender Standort antworten identisch mit 404. Verlor die Person hinter dem Grant den Zugriff auf den Mandanten, liefert die Liste ein leeres Array — nie fremde Standorte.
Bist du ein Fallabwickler- oder Gutachter-Mandant, liegen genau die zwei Standorte, die du pro Fall
brauchst, außerhalb deines Teilbaums — hier bekommst du für sie also 404. Nimm dafür
GET /cases/{caseId}/locations: dort
hängt die Berechtigung am Fall statt am Standort und du erhältst beide Anschriften in einem Aufruf.
Fallabwickler
GET /api/external/v1/case-handlers (Scope reference-data:read)
Liefert die Fallabwickler-Standorte, die für deinen Mandanten relevant sind: die aus den eigenen
Standorten heraus zugewiesenen (Haftpflicht- und Eigenverschulden-Routing) plus alle
Fallabwickler-Standorte innerhalb deines Mandanten-Teilbaums. Jeder Eintrag ist ein schlanker
Standort (locationCode, name, partner, mainLocation, type, ownProcessingAllowed) —
z. B. {"locationCode": "musterhandler", "name": "Musterhandler GmbH", "type": "CASE_HANDLER", …}.
Am Fall steht dieser Code dann im Feld caseHandler.
Zwei Dinge, die du wissen solltest:
- Der Betreiber-Standort (
type: ADMIN) steht mit in der Liste. Er ist selbst ein Fallabwickler — und zwar der häufigste: an einem großen Teil aller Fälle steht sein Code incaseHandler. Ihn auszublenden hieße, den häufigsten Wert nicht auflösen zu können. - Du wählst den Fallabwickler nicht aus. Das Feld
caseHandleram Fall wird serverseitig aus Standort und Schadenart abgeleitet. Diese Liste dient der Auflösung des Codes zu einem Namen — nicht der Zuweisung.
Kolleg_innen
GET /api/external/v1/users (Scope reference-data:read)
GET /api/external/v1/users/{username} (Scope reference-data:read)
Dein Verzeichnis für username → Name. Jeder Autor eines Falls oder Kommentars, den du sehen
kannst, löst hier auf.
| Feld | Inhalt |
|---|---|
username | Benutzername — der Wert, der in createdBy/lastModifiedBy eines Falls und in createdBy eines Kommentars steht |
firstName, lastName | Name |
directColleague | ob die Person zu deinem Mandanten gehört (siehe unten) |
mainLocationCode | Standortcode der Hauptgruppe — immer der Hauptstandort, nie eine Filiale (musterhaus/nord ⇒ musterhaus) |
mainLocationType | LOCATION (Werkstatt), CASE_HANDLER, APPRAISER oder ADMIN |
Es erscheinen ausschließlich echte Personen mit aktivem Konto — deaktivierte, versteckte und technische Konten nie.
Wen du siehst — und was directColleague bedeutet
Die Liste umfasst beide Seiten der Zuordnung:
- die Personen deiner eigenen Gruppe (Mandanten-Root samt Unterstandorten) →
directColleague: true - die Personen der Standorte, mit denen dein Mandant über das Routing verbunden ist →
directColleague: false— aus Fallabwickler-Sicht die betreuten Werkstätten und die ihnen zugewiesenen Gutachterbüros, aus Gutachter-Sicht die Standorte, die dein Büro als Gutachter führen
Das Flag ist mandantenrelativ: dieselbe Person ist für den einen Key ein direkter Kollege und für den anderen nicht. Es ersetzt jede Ableitung über Standortcodes — du kannst die eigene Seite von der Gegenseite unterscheiden, ohne einen einzigen Code zu kennen. Der typische Anwendungsfall: Kommentare eigener Leute lösen im Fremdsystem keine Benachrichtigung aus, Kommentare der Gegenseite schon.
Ein ADMIN-Standort expandiert auf jede Werkstatt der Plattform — Betreiber administrieren alles, und dieser Endpunkt bildet das ab. Die Fall-Sicht bleibt davon unberührt: auch ein Betreiber-Key bekommt nur die an ihn gerouteten Fälle.
Der Einzelabruf ist enger gefasst als sein internes Gegenstück: er löst ausschließlich innerhalb dieser Menge auf. Ein unbekannter Benutzername und einer außerhalb der Sichtbarkeit antworten beide mit 404.
Versicherungen
GET /api/external/v1/insurances (Scope reference-data:read)
GET /api/external/v1/insurances/{id} (Scope reference-data:read)
GET /api/external/v1/legal-insurances (Scope reference-data:read)
GET /api/external/v1/legal-insurances/{id} (Scope reference-data:read)
POST /api/external/v1/insurances (Scope reference-data:write + Operator-Konto)
PUT /api/external/v1/insurances/{id} (Scope reference-data:write + Operator-Konto)
Zwei getrennte Kataloge: Kfz-Versicherungen (/insurances, Typ CAR_INSURANCE) und
Rechtsschutzversicherungen (/legal-insurances, Typ LEGAL_INSURANCE). Ein Eintrag besteht aus
insuranceId, displayName und type.
Die insuranceId ist ein Stammdaten-Schlüssel als String, keine UUID (z. B. "5312"). Sie
steht am Fall in vehicleInsuranceId, opponentInsuranceId und legalInsuranceId.
Primärschlüssel ist das Paar aus insuranceId und type — dieselbe Nummer kann in beiden
Katalogen existieren.
Schreiben
POST /insuranceslegt an.insuranceId,displayNameundtypesind Pflicht;typeentscheidet, in welchem Katalog der Eintrag landet. Existiert das Paar bereits ⇒ 409CONFLICT. Antwort: 201 mit dem angelegten Eintrag.PUT /insurances/{id}aktualisiert. Die Pfad-idgewinnt immer über eine abweichendeinsuranceIdim Body — so kann ein Tippfehler im Body keinen fremden Katalogeintrag überschreiben. Gibt es das Paar ausidundtypenicht ⇒ 404NOT_FOUND.- Ein Löschen gibt es nicht.
- Beide Schreibpfade verlangen zusätzlich zum Scope ein Operator-Konto hinter der Freigabe
(ADMIN-Standort-Mitgliedschaft). Fehlt es, antworten sie 403
ACCESS_DENIED— auch mit gesetztemreference-data:write.
Der Versicherungskatalog ist nicht mandantengebunden. Ein neuer oder umbenannter Eintrag ist
sofort für jeden Mandanten der Plattform sichtbar und auswählbar. Genau deshalb ist der Schreibpfad
doppelt abgesichert: Scope reference-data:write und Operator-Konto. Stimm die Nummernvergabe
mit dem Betreiber ab.
Werte, die kein Endpunkt liefert
Für diese Auswahlwerte gibt es keine Abfrage: es sind Enums im DTO. Ihre gültigen Werte stehen im OpenAPI-Schema des jeweiligen Feldes und, soweit fachlich relevant, im Glossar.
| Enum | Beispielwerte |
|---|---|
CaseStatus | WORK_IN_PROGRESS, WAITING_FOR_CUSTOMER, RELEASED, HANDED_OVER_APPRAISER, CLOSED, CANCELLED, HIDDEN |
CaseTag | NONE, LIABILITY_CONFIRMATION_ISSUED, RENTAL_CAR_PRICE_INFORMATION_RECEIVED, ADVANCE_RECEIVED |
AttachmentTag | 24 Werte, u. a. POA, POA_SIGNED, EXPERT_OPINION_ORDER_SIGNED, PICTURE, INVOICE_REPAIR |
DamageType | NONE, THIRD_PARTY_LIABILITY, OWN_FAULT |
ProcessingType | HANDLER_PROCESSING, OWN_PROCESSING |
LocationType | LOCATION, CASE_HANDLER, APPRAISER, ADMIN |
InsuranceType | CAR_INSURANCE, LEGAL_INSURANCE |
Title, Kind, Country, Ownership, Roadworthiness, RepairDecision, RentalDecision, DecisionEnum, Reporter, Advisory | Auswahlwerte der Formularfelder eines Falls |
Sende nur Werte, die du gelesen hast oder die dokumentiert sind — ein unbekannter Enum-Wert führt zu
einem Framework-400 ohne code.
Noch nicht verfügbar
| Fähigkeit | Stand |
|---|---|
| PLZ-/Ort-Datensatz | existiert extern nicht |
| Gutachterbüros frei durchsuchen | existiert extern nicht — die Anschrift des am Fall zugewiesenen Büros liefert GET /cases/{caseId}/locations |
| Mitarbeiter_innen eines Gutachterbüros abfragen (Kaskade) | existiert extern nicht; am Fall stehen expertEmployee/expertReference bereits aufgelöst |
| Standorte, Benutzer oder Themes anlegen/ändern | ist und bleibt Administration (nicht extern) |
Caching-Empfehlung
Standorte, Fallabwickler und Versicherungen ändern sich selten. Lade sie einmal beim Start deines Sync-Laufs in einen lokalen Cache, statt sie pro Fall abzufragen — das schont dein Minuten-Rate-Limit erheblich. Kolleg_innen ändern sich häufiger, aber selten innerhalb eines Laufs.