{
    "openapi": "3.1.0",
    "info": {
        "title": "TheraPlanner API",
        "version": "v1",
        "description": "Öffentliche API der Praxisverwaltung TheraPlanner."
    },
    "servers": [
        {
            "url": "/api/v1",
            "description": "Diese Installation"
        }
    ],
    "security": [
        {
            "bearerAuth": []
        }
    ],
    "tags": [
        {
            "name": "Patient:innen"
        },
        {
            "name": "Dokumente"
        },
        {
            "name": "Termine"
        },
        {
            "name": "Räume"
        },
        {
            "name": "Verordnungen"
        },
        {
            "name": "Rechnungen"
        },
        {
            "name": "Praxis"
        },
        {
            "name": "Konto"
        },
        {
            "name": "Mitteilungen"
        },
        {
            "name": "Aufgaben"
        },
        {
            "name": "Anmeldung"
        },
        {
            "name": "Zutritt"
        }
    ],
    "paths": {
        "/access/log": {
            "post": {
                "operationId": "api_v1_access_log",
                "summary": "Zutrittsentscheidung melden",
                "tags": [
                    "Zutritt"
                ],
                "parameters": [],
                "responses": {
                    "201": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/AccessLogEntry"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "access:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "occurredAt": {
                                        "type": "string",
                                        "format": "date-time"
                                    },
                                    "result": {
                                        "type": "string",
                                        "enum": [
                                            "granted",
                                            "denied"
                                        ]
                                    },
                                    "personId": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 64
                                    },
                                    "credentialType": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "pin",
                                            "nfc"
                                        ]
                                    },
                                    "area": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 32
                                    },
                                    "reason": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 64
                                    }
                                },
                                "required": [
                                    "occurredAt",
                                    "result"
                                ],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/access/snapshot": {
            "get": {
                "operationId": "api_v1_access_snapshot",
                "summary": "Vollständiger Zutrittsstand",
                "tags": [
                    "Zutritt"
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/AccessSnapshot"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "access:read"
                        ]
                    }
                ]
            }
        },
        "/account": {
            "get": {
                "operationId": "api_v1_account_show",
                "summary": "Das eigene Konto",
                "tags": [
                    "Konto"
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Account"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "account:read"
                        ]
                    }
                ]
            }
        },
        "/account/push-token": {
            "put": {
                "operationId": "api_v1_account_push-token_update",
                "summary": "Push-Token des Geräts setzen",
                "tags": [
                    "Konto"
                ],
                "parameters": [],
                "responses": {
                    "204": {
                        "description": "Erledigt, kein Rumpf."
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "account:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "token": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 255
                                    }
                                },
                                "required": [],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/account/sessions": {
            "get": {
                "operationId": "api_v1_account_sessions_index",
                "summary": "Sitzungen des eigenen Kontos",
                "tags": [
                    "Konto"
                ],
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        },
                        "description": "Seitengröße."
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Unverändert aus links.next der vorherigen Antwort. Es gibt keinen Offset: er wäre bei nebenläufigen Änderungen falsch."
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Sortierung, kommagetrennt, \"-\" für absteigend. Erlaubt: createdAt, updatedAt, birthDate, status. Nicht sortierbar, weil verschlüsselt gespeichert: lastName, firstName, email, phone, mobile, city, postalCode, street. Ein anderes Feld wird mit 422 ABGEWIESEN und nicht ignoriert."
                    },
                    {
                        "name": "include",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Verknüpfte Objekte, kommagetrennt: consents."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Session"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "account:read"
                        ]
                    }
                ]
            }
        },
        "/account/sessions/{session}": {
            "delete": {
                "operationId": "api_v1_account_sessions_destroy",
                "summary": "Sitzung beenden",
                "tags": [
                    "Konto"
                ],
                "parameters": [
                    {
                        "name": "session",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "204": {
                        "description": "Erledigt, kein Rumpf."
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "account:write"
                        ]
                    }
                ]
            }
        },
        "/account/tokens": {
            "get": {
                "operationId": "api_v1_account_tokens_index",
                "summary": "Tokens des eigenen Kontos",
                "tags": [
                    "Konto"
                ],
                "parameters": [
                    {
                        "name": "includeRevoked",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Auch widerrufene Tokens liefern."
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        },
                        "description": "Seitengröße."
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Unverändert aus links.next der vorherigen Antwort. Es gibt keinen Offset: er wäre bei nebenläufigen Änderungen falsch."
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Sortierung, kommagetrennt, \"-\" für absteigend. Erlaubt: createdAt, updatedAt, birthDate, status. Nicht sortierbar, weil verschlüsselt gespeichert: lastName, firstName, email, phone, mobile, city, postalCode, street. Ein anderes Feld wird mit 422 ABGEWIESEN und nicht ignoriert."
                    },
                    {
                        "name": "include",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Verknüpfte Objekte, kommagetrennt: consents."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/ApiToken"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "account:read"
                        ]
                    }
                ]
            },
            "post": {
                "operationId": "api_v1_account_tokens_store",
                "summary": "Token ausstellen",
                "tags": [
                    "Konto"
                ],
                "parameters": [],
                "responses": {
                    "201": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/ApiToken"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "account:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 120
                                    },
                                    "deviceName": {
                                        "type": "string",
                                        "maxLength": 120
                                    },
                                    "abilities": {
                                        "type": [
                                            "array",
                                            "null"
                                        ],
                                        "items": {
                                            "type": "string",
                                            "maxLength": 64
                                        }
                                    },
                                    "expiresAt": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "date-time"
                                    }
                                },
                                "required": [
                                    "name",
                                    "deviceName"
                                ],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/account/tokens/{token}": {
            "delete": {
                "operationId": "api_v1_account_tokens_destroy",
                "summary": "Token widerrufen",
                "tags": [
                    "Konto"
                ],
                "parameters": [
                    {
                        "name": "token",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "204": {
                        "description": "Erledigt, kein Rumpf."
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "account:write"
                        ]
                    }
                ]
            }
        },
        "/appointments": {
            "get": {
                "operationId": "api_v1_appointments_index",
                "summary": "Termine auflisten",
                "tags": [
                    "Termine"
                ],
                "parameters": [
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Beginn des Zeitraums (ISO 8601), einschließlich."
                    },
                    {
                        "name": "until",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Ende des Zeitraums (ISO 8601), ausschließlich."
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Terminstatus, kommagetrennt."
                    },
                    {
                        "name": "patientId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Auf eine Akte einschränken (ULID)."
                    },
                    {
                        "name": "practitionerId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Auf eine behandelnde Person einschränken (ULID)."
                    },
                    {
                        "name": "roomId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Auf einen Raum einschränken (ULID)."
                    },
                    {
                        "name": "locationId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Auf einen Standort einschränken (ULID). Über den Raum - Termine ohne Raum fallen heraus."
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        },
                        "description": "Seitengröße."
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Unverändert aus links.next der vorherigen Antwort. Es gibt keinen Offset: er wäre bei nebenläufigen Änderungen falsch."
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Sortierung, kommagetrennt, \"-\" für absteigend. Erlaubt: startsAt, endsAt, createdAt, updatedAt, status. Nicht sortierbar, weil verschlüsselt gespeichert: treatmentNote, internalNote, cancellationReason. Ein anderes Feld wird mit 422 ABGEWIESEN und nicht ignoriert."
                    },
                    {
                        "name": "include",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Verknüpfte Objekte, kommagetrennt: patient, type, practitioner, room."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Appointment"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "appointments:read"
                        ]
                    }
                ]
            },
            "post": {
                "operationId": "api_v1_appointments_store",
                "summary": "Termin anlegen",
                "tags": [
                    "Termine"
                ],
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "maxLength": 255
                        },
                        "description": "Pflicht. Eine Wiederholung mit demselben Schlüssel liefert die erste Antwort erneut, statt einen zweiten Datensatz anzulegen."
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Appointment"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "appointments:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "appointmentTypeId": {
                                        "type": "string",
                                        "format": "ulid"
                                    },
                                    "practitionerId": {
                                        "type": "string",
                                        "format": "ulid"
                                    },
                                    "startsAt": {
                                        "type": "string",
                                        "format": "date-time"
                                    },
                                    "durationMinutes": {
                                        "type": [
                                            "integer",
                                            "null"
                                        ],
                                        "minimum": 1,
                                        "maximum": 1440
                                    },
                                    "patientId": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "ulid"
                                    },
                                    "roomId": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "ulid"
                                    },
                                    "title": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 190
                                    },
                                    "treatmentNote": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 5000
                                    },
                                    "internalNote": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 5000
                                    }
                                },
                                "required": [
                                    "appointmentTypeId",
                                    "practitionerId",
                                    "startsAt"
                                ],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/appointments/free-slots": {
            "get": {
                "operationId": "api_v1_appointments_free-slots",
                "summary": "Freie Zeitfenster berechnen",
                "tags": [
                    "Termine"
                ],
                "parameters": [
                    {
                        "name": "appointmentTypeId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Terminart (ULID). Pflicht - sie bestimmt Dauer und Rüstzeiten."
                    },
                    {
                        "name": "practitionerId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Behandelnde Person (ULID). Pflicht."
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Beginn des Zeitraums (ISO 8601). Pflicht."
                    },
                    {
                        "name": "until",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Ende des Zeitraums (ISO 8601). Pflicht, höchstens 92 Tage nach \"from\"."
                    },
                    {
                        "name": "roomId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Auf einen Raum einschränken (ULID)."
                    },
                    {
                        "name": "durationMinutes",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Abweichende Dauer."
                    },
                    {
                        "name": "stepMinutes",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Schrittweite des Rasters."
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Höchstzahl an Fenstern."
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        },
                        "description": "Seitengröße."
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Unverändert aus links.next der vorherigen Antwort. Es gibt keinen Offset: er wäre bei nebenläufigen Änderungen falsch."
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Sortierung, kommagetrennt, \"-\" für absteigend. Erlaubt: startsAt, endsAt, createdAt, updatedAt, status. Nicht sortierbar, weil verschlüsselt gespeichert: treatmentNote, internalNote, cancellationReason. Ein anderes Feld wird mit 422 ABGEWIESEN und nicht ignoriert."
                    },
                    {
                        "name": "include",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Verknüpfte Objekte, kommagetrennt: patient, type, practitioner, room."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/FreeSlot"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "appointments:read"
                        ]
                    }
                ]
            }
        },
        "/appointments/{appointment}": {
            "get": {
                "operationId": "api_v1_appointments_show",
                "summary": "Termin lesen",
                "tags": [
                    "Termine"
                ],
                "parameters": [
                    {
                        "name": "appointment",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Appointment"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "appointments:read"
                        ]
                    }
                ]
            }
        },
        "/appointments/{appointment}/cancel": {
            "post": {
                "operationId": "api_v1_appointments_cancel",
                "summary": "Termin absagen",
                "tags": [
                    "Termine"
                ],
                "parameters": [
                    {
                        "name": "appointment",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    },
                    {
                        "name": "If-Match",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Pflicht. Das ETag aus dem letzten Lesen. Ohne den Kopfeintrag: 428, bei veraltetem Wert: 412."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Appointment"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "appointments:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "reason": {
                                        "type": "string",
                                        "maxLength": 1000
                                    },
                                    "reasonCode": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "patient_cancelled",
                                            "patient_sick",
                                            "patient_no_show",
                                            "rescheduled",
                                            "practice_cancelled",
                                            "practitioner_sick",
                                            "prescription_expired",
                                            "other"
                                        ]
                                    },
                                    "scope": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "this_occurrence",
                                            "this_and_following"
                                        ]
                                    }
                                },
                                "required": [
                                    "reason"
                                ],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/appointments/{appointment}/reschedule": {
            "post": {
                "operationId": "api_v1_appointments_reschedule",
                "summary": "Termin verschieben",
                "tags": [
                    "Termine"
                ],
                "parameters": [
                    {
                        "name": "appointment",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    },
                    {
                        "name": "If-Match",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Pflicht. Das ETag aus dem letzten Lesen. Ohne den Kopfeintrag: 428, bei veraltetem Wert: 412."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Appointment"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "appointments:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "startsAt": {
                                        "type": "string",
                                        "format": "date-time"
                                    },
                                    "durationMinutes": {
                                        "type": [
                                            "integer",
                                            "null"
                                        ],
                                        "minimum": 1,
                                        "maximum": 1440
                                    },
                                    "roomId": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "ulid"
                                    },
                                    "detachRoom": {
                                        "type": [
                                            "boolean",
                                            "null"
                                        ]
                                    }
                                },
                                "required": [
                                    "startsAt"
                                ],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/appointments/{appointment}/status": {
            "post": {
                "operationId": "api_v1_appointments_status",
                "summary": "Terminstatus setzen",
                "tags": [
                    "Termine"
                ],
                "parameters": [
                    {
                        "name": "appointment",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Appointment"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "appointments:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "status": {
                                        "type": "string",
                                        "enum": [
                                            "scheduled",
                                            "confirmed",
                                            "attended",
                                            "no_show"
                                        ]
                                    },
                                    "reason": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 500
                                    }
                                },
                                "required": [
                                    "status"
                                ],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/auth/login": {
            "post": {
                "operationId": "api_v1_auth_login",
                "summary": "Anmelden (Praxis-App)",
                "tags": [
                    "Anmeldung"
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/LoginStep"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "email": {
                                        "type": "string",
                                        "format": "email",
                                        "maxLength": 255
                                    },
                                    "password": {
                                        "type": "string",
                                        "maxLength": 1024
                                    },
                                    "deviceName": {
                                        "type": "string",
                                        "maxLength": 120
                                    },
                                    "practiceId": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 26
                                    }
                                },
                                "required": [
                                    "email",
                                    "password",
                                    "deviceName"
                                ],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/auth/two-factor": {
            "post": {
                "operationId": "api_v1_auth_two-factor",
                "summary": "Anmeldung fortsetzen: zweiter Faktor, Praxiswahl",
                "tags": [
                    "Anmeldung"
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/LoginStep"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "challenge": {
                                        "type": "string",
                                        "maxLength": 4096
                                    },
                                    "code": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 64
                                    },
                                    "practiceId": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 26
                                    }
                                },
                                "required": [
                                    "challenge"
                                ],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/invoices": {
            "get": {
                "operationId": "api_v1_invoices_index",
                "summary": "Rechnungen auflisten",
                "tags": [
                    "Rechnungen"
                ],
                "parameters": [
                    {
                        "name": "patientId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Auf eine Akte einschränken (ULID)."
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Rechnungsstatus, kommagetrennt."
                    },
                    {
                        "name": "issuedFrom",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Ausgestellt ab (JJJJ-MM-TT)."
                    },
                    {
                        "name": "issuedTo",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Ausgestellt bis (JJJJ-MM-TT)."
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        },
                        "description": "Seitengröße."
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Unverändert aus links.next der vorherigen Antwort. Es gibt keinen Offset: er wäre bei nebenläufigen Änderungen falsch."
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Sortierung, kommagetrennt, \"-\" für absteigend. Erlaubt: issuedOn, dueOn, createdAt, updatedAt, status, totalGrossCents. Ein anderes Feld wird mit 422 ABGEWIESEN und nicht ignoriert."
                    },
                    {
                        "name": "include",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Verknüpfte Objekte, kommagetrennt: items."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Invoice"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "invoices:read"
                        ]
                    }
                ]
            }
        },
        "/invoices/{invoice}": {
            "get": {
                "operationId": "api_v1_invoices_show",
                "summary": "Rechnung lesen",
                "tags": [
                    "Rechnungen"
                ],
                "parameters": [
                    {
                        "name": "invoice",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Invoice"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "invoices:read"
                        ]
                    }
                ]
            }
        },
        "/invoices/{invoice}/document": {
            "get": {
                "operationId": "api_v1_invoices_document",
                "summary": "Rechnung als PDF",
                "tags": [
                    "Rechnungen"
                ],
                "parameters": [
                    {
                        "name": "invoice",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "content": {
                            "application/pdf": {
                                "schema": {
                                    "type": "string",
                                    "format": "binary"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "invoices:read"
                        ]
                    }
                ]
            }
        },
        "/invoices/{invoice}/payments": {
            "post": {
                "operationId": "api_v1_invoices_payments_store",
                "summary": "Zahlungseingang erfassen",
                "tags": [
                    "Rechnungen"
                ],
                "parameters": [
                    {
                        "name": "invoice",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "maxLength": 255
                        },
                        "description": "Pflicht. Eine Wiederholung mit demselben Schlüssel liefert die erste Antwort erneut, statt einen zweiten Datensatz anzulegen."
                    },
                    {
                        "name": "If-Match",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Pflicht. Das ETag aus dem letzten Lesen. Ohne den Kopfeintrag: 428, bei veraltetem Wert: 412."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Invoice"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "invoices:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "amountCents": {
                                        "type": [
                                            "integer",
                                            "null"
                                        ],
                                        "minimum": 1
                                    },
                                    "paidAt": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "date-time"
                                    },
                                    "method": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "transfer",
                                            "cash",
                                            "card",
                                            "direct_debit",
                                            "unknown"
                                        ]
                                    },
                                    "reference": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 64
                                    }
                                },
                                "required": [],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/notifications": {
            "get": {
                "operationId": "api_v1_notifications_index",
                "summary": "Mitteilungen des eigenen Kontos",
                "tags": [
                    "Mitteilungen"
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Notification"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "account:read"
                        ]
                    }
                ]
            }
        },
        "/notifications/read": {
            "post": {
                "operationId": "api_v1_notifications_read",
                "summary": "Mitteilungen als gelesen markieren",
                "tags": [
                    "Mitteilungen"
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/NotificationReadState"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "account:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "ids": {
                                        "type": [
                                            "array",
                                            "null"
                                        ],
                                        "items": {
                                            "type": "string",
                                            "maxLength": 64
                                        }
                                    },
                                    "all": {
                                        "type": [
                                            "boolean",
                                            "null"
                                        ]
                                    }
                                },
                                "required": [],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/patients": {
            "get": {
                "operationId": "api_v1_patients_index",
                "summary": "Akten auflisten",
                "tags": [
                    "Patient:innen"
                ],
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Aktenstatus, kommagetrennt. Ohne Angabe nur active und inactive."
                    },
                    {
                        "name": "birthDateFrom",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Geburtsdatum ab (JJJJ-MM-TT)."
                    },
                    {
                        "name": "birthDateTo",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Geburtsdatum bis (JJJJ-MM-TT)."
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        },
                        "description": "Seitengröße."
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Unverändert aus links.next der vorherigen Antwort. Es gibt keinen Offset: er wäre bei nebenläufigen Änderungen falsch."
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Sortierung, kommagetrennt, \"-\" für absteigend. Erlaubt: createdAt, updatedAt, birthDate, status. Nicht sortierbar, weil verschlüsselt gespeichert: lastName, firstName, email, phone, mobile, city, postalCode, street. Ein anderes Feld wird mit 422 ABGEWIESEN und nicht ignoriert."
                    },
                    {
                        "name": "include",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Verknüpfte Objekte, kommagetrennt: consents."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Patient"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "patients:read"
                        ]
                    }
                ]
            },
            "post": {
                "operationId": "api_v1_patients_store",
                "summary": "Akte anlegen",
                "tags": [
                    "Patient:innen"
                ],
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "maxLength": 255
                        },
                        "description": "Pflicht. Eine Wiederholung mit demselben Schlüssel liefert die erste Antwort erneut, statt einen zweiten Datensatz anzulegen."
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Patient"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "patients:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "lastName": {
                                        "type": "string",
                                        "maxLength": 120
                                    },
                                    "firstName": {
                                        "type": "string",
                                        "maxLength": 120
                                    },
                                    "gender": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "M",
                                            "F",
                                            "D"
                                        ]
                                    },
                                    "birthDate": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "date-time"
                                    },
                                    "status": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "active",
                                            "inactive",
                                            "archived",
                                            "merged"
                                        ]
                                    },
                                    "guardianFirstName": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 120
                                    },
                                    "guardianLastName": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 120
                                    },
                                    "guardianGender": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "M",
                                            "F",
                                            "D"
                                        ]
                                    },
                                    "healthInsurance": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 190
                                    },
                                    "insuranceType": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "public",
                                            "public_additional",
                                            "private",
                                            "private_assistance"
                                        ]
                                    },
                                    "phone": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 40
                                    },
                                    "mobile": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 40
                                    },
                                    "email": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "email",
                                        "maxLength": 190
                                    },
                                    "street": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 190
                                    },
                                    "postalCode": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 16
                                    },
                                    "city": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 120
                                    },
                                    "doctor": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 190
                                    },
                                    "diagnosis": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 2000
                                    },
                                    "anamnesis": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 5000
                                    },
                                    "notes": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 5000
                                    }
                                },
                                "required": [
                                    "lastName",
                                    "firstName"
                                ],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/patients/search": {
            "get": {
                "operationId": "api_v1_patients_search",
                "summary": "Akten suchen (über Blind Index)",
                "tags": [
                    "Patient:innen"
                ],
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Suchbegriff: Nachname, Vorname, E-Mail oder Rufnummer. Bei NAMEN genuegt der Wortanfang ab zwei Buchstaben (\"Mül\" findet \"Müller\", \"Ann Mül\" die Anna Müller); bei E-Mail und Rufnummer wird exakt gesucht. Die Wortmitte trifft nicht - siehe die Beschreibung der Sammlung. Welche der beiden Suchen gelaufen ist, steht in meta.exact."
                    },
                    {
                        "name": "field",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Suchfeld erzwingen: last_name, first_name, email, phone."
                    },
                    {
                        "name": "includeArchived",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Archivierte Akten einbeziehen."
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        },
                        "description": "Seitengröße."
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Unverändert aus links.next der vorherigen Antwort. Es gibt keinen Offset: er wäre bei nebenläufigen Änderungen falsch."
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Sortierung, kommagetrennt, \"-\" für absteigend. Erlaubt: createdAt, updatedAt, birthDate, status. Nicht sortierbar, weil verschlüsselt gespeichert: lastName, firstName, email, phone, mobile, city, postalCode, street. Ein anderes Feld wird mit 422 ABGEWIESEN und nicht ignoriert."
                    },
                    {
                        "name": "include",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Verknüpfte Objekte, kommagetrennt: consents."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Patient"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "patients:read"
                        ]
                    }
                ]
            }
        },
        "/patients/{patient}": {
            "get": {
                "operationId": "api_v1_patients_show",
                "summary": "Akte lesen",
                "tags": [
                    "Patient:innen"
                ],
                "parameters": [
                    {
                        "name": "patient",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Patient"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "patients:read"
                        ]
                    }
                ]
            },
            "patch": {
                "operationId": "api_v1_patients_update",
                "summary": "Akte ändern",
                "tags": [
                    "Patient:innen"
                ],
                "parameters": [
                    {
                        "name": "patient",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    },
                    {
                        "name": "If-Match",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Pflicht. Das ETag aus dem letzten Lesen. Ohne den Kopfeintrag: 428, bei veraltetem Wert: 412."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Patient"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "patients:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "lastName": {
                                        "type": "string",
                                        "maxLength": 120
                                    },
                                    "firstName": {
                                        "type": "string",
                                        "maxLength": 120
                                    },
                                    "gender": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "M",
                                            "F",
                                            "D"
                                        ]
                                    },
                                    "birthDate": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "date-time"
                                    },
                                    "status": {
                                        "type": "string",
                                        "enum": [
                                            "active",
                                            "inactive",
                                            "archived",
                                            "merged"
                                        ]
                                    },
                                    "guardianFirstName": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 120
                                    },
                                    "guardianLastName": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 120
                                    },
                                    "guardianGender": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "M",
                                            "F",
                                            "D"
                                        ]
                                    },
                                    "healthInsurance": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 190
                                    },
                                    "insuranceType": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "public",
                                            "public_additional",
                                            "private",
                                            "private_assistance"
                                        ]
                                    },
                                    "phone": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 40
                                    },
                                    "mobile": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 40
                                    },
                                    "email": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "email",
                                        "maxLength": 190
                                    },
                                    "street": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 190
                                    },
                                    "postalCode": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 16
                                    },
                                    "city": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 120
                                    },
                                    "doctor": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 190
                                    },
                                    "diagnosis": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 2000
                                    },
                                    "anamnesis": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 5000
                                    },
                                    "notes": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 5000
                                    }
                                },
                                "required": [],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/patients/{patient}/consents": {
            "get": {
                "operationId": "api_v1_patients_consents_index",
                "summary": "Einwilligungen auflisten",
                "tags": [
                    "Patient:innen"
                ],
                "parameters": [
                    {
                        "name": "patient",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        },
                        "description": "Seitengröße."
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Unverändert aus links.next der vorherigen Antwort. Es gibt keinen Offset: er wäre bei nebenläufigen Änderungen falsch."
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Sortierung, kommagetrennt, \"-\" für absteigend. Erlaubt: createdAt, updatedAt, birthDate, status. Nicht sortierbar, weil verschlüsselt gespeichert: lastName, firstName, email, phone, mobile, city, postalCode, street. Ein anderes Feld wird mit 422 ABGEWIESEN und nicht ignoriert."
                    },
                    {
                        "name": "include",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Verknüpfte Objekte, kommagetrennt: consents."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Consent"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "patients:read"
                        ]
                    }
                ]
            },
            "post": {
                "operationId": "api_v1_patients_consents_grant",
                "summary": "Einwilligung erteilen",
                "tags": [
                    "Patient:innen"
                ],
                "parameters": [
                    {
                        "name": "patient",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "maxLength": 255
                        },
                        "description": "Pflicht. Eine Wiederholung mit demselben Schlüssel liefert die erste Antwort erneut, statt einen zweiten Datensatz anzulegen."
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Consent"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "patients:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "purpose": {
                                        "type": "string",
                                        "enum": [
                                            "appointment_reminder",
                                            "invoice_delivery",
                                            "document_delivery",
                                            "practice_notice"
                                        ]
                                    },
                                    "channel": {
                                        "type": "string",
                                        "enum": [
                                            "sms",
                                            "email",
                                            "whatsapp"
                                        ]
                                    },
                                    "evidence": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 1000
                                    },
                                    "note": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 1000
                                    }
                                },
                                "required": [
                                    "purpose",
                                    "channel"
                                ],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/patients/{patient}/consents/revoke": {
            "post": {
                "operationId": "api_v1_patients_consents_revoke",
                "summary": "Einwilligung widerrufen",
                "tags": [
                    "Patient:innen"
                ],
                "parameters": [
                    {
                        "name": "patient",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "maxLength": 255
                        },
                        "description": "Pflicht. Eine Wiederholung mit demselben Schlüssel liefert die erste Antwort erneut, statt einen zweiten Datensatz anzulegen."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Consent"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "patients:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "purpose": {
                                        "type": "string",
                                        "enum": [
                                            "appointment_reminder",
                                            "invoice_delivery",
                                            "document_delivery",
                                            "practice_notice"
                                        ]
                                    },
                                    "channel": {
                                        "type": "string",
                                        "enum": [
                                            "sms",
                                            "email",
                                            "whatsapp"
                                        ]
                                    },
                                    "evidence": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 1000
                                    },
                                    "note": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 1000
                                    }
                                },
                                "required": [
                                    "purpose",
                                    "channel"
                                ],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/patients/{patient}/documents": {
            "get": {
                "operationId": "api_v1_patients_documents_index",
                "summary": "Belege zu einer Akte",
                "tags": [
                    "Dokumente"
                ],
                "parameters": [
                    {
                        "name": "patient",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        },
                        "description": "Seitengröße."
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Unverändert aus links.next der vorherigen Antwort. Es gibt keinen Offset: er wäre bei nebenläufigen Änderungen falsch."
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Sortierung, kommagetrennt, \"-\" für absteigend. Erlaubt: createdAt, updatedAt, birthDate, status. Nicht sortierbar, weil verschlüsselt gespeichert: lastName, firstName, email, phone, mobile, city, postalCode, street. Ein anderes Feld wird mit 422 ABGEWIESEN und nicht ignoriert."
                    },
                    {
                        "name": "include",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Verknüpfte Objekte, kommagetrennt: consents."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Document"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "documents:read"
                        ]
                    }
                ]
            }
        },
        "/patients/{patient}/files": {
            "get": {
                "operationId": "api_v1_patients_files_index",
                "summary": "Abgelegte Dokumente einer Akte",
                "tags": [
                    "Dokumente"
                ],
                "parameters": [
                    {
                        "name": "patient",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/PatientFile"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "documents:read"
                        ]
                    }
                ]
            },
            "post": {
                "operationId": "api_v1_patients_files_store",
                "summary": "Direkt-Upload abschließen (Dokument ablegen)",
                "tags": [
                    "Dokumente"
                ],
                "parameters": [
                    {
                        "name": "patient",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "maxLength": 255
                        },
                        "description": "Pflicht. Eine Wiederholung mit demselben Schlüssel liefert die erste Antwort erneut, statt einen zweiten Datensatz anzulegen."
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/PatientFile"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "documents:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "upload": {
                                        "type": "string",
                                        "maxLength": 4096
                                    },
                                    "title": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "category": {
                                        "type": "string",
                                        "enum": [
                                            "doctor_letter",
                                            "prescription",
                                            "finding",
                                            "certificate",
                                            "consent",
                                            "photo",
                                            "correspondence",
                                            "other"
                                        ]
                                    },
                                    "issuedOn": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "date"
                                    },
                                    "isClinical": {
                                        "type": [
                                            "boolean",
                                            "null"
                                        ]
                                    }
                                },
                                "required": [
                                    "upload",
                                    "title",
                                    "category"
                                ],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/patients/{patient}/files/uploads": {
            "post": {
                "operationId": "api_v1_patients_files_uploads_store",
                "summary": "Direkt-Upload vorbereiten (vorsignierte Adresse)",
                "tags": [
                    "Dokumente"
                ],
                "parameters": [
                    {
                        "name": "patient",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/FileUpload"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "documents:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 255
                                    },
                                    "size": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 99614720
                                    },
                                    "type": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 100
                                    }
                                },
                                "required": [
                                    "name",
                                    "size"
                                ],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/practice": {
            "get": {
                "operationId": "api_v1_practice_show",
                "summary": "Stammdaten der eigenen Praxis",
                "tags": [
                    "Praxis"
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Practice"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "practice:read"
                        ]
                    }
                ]
            }
        },
        "/practice/appointment-types": {
            "get": {
                "operationId": "api_v1_practice_appointment-types",
                "summary": "Terminarten der Praxis",
                "tags": [
                    "Praxis"
                ],
                "parameters": [
                    {
                        "name": "includeInactive",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Auch stillgelegte Terminarten liefern."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/AppointmentType"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "practice:read"
                        ]
                    }
                ]
            }
        },
        "/practice/members": {
            "get": {
                "operationId": "api_v1_practice_members",
                "summary": "Mitglieder der Praxis",
                "tags": [
                    "Praxis"
                ],
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Mitgliedschaftsstatus, kommagetrennt."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Member"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "practice:read"
                        ]
                    }
                ]
            }
        },
        "/practice/opening-hours": {
            "get": {
                "operationId": "api_v1_practice_opening-hours",
                "summary": "Öffnungszeiten",
                "tags": [
                    "Praxis"
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/OpeningHour"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "practice:read"
                        ]
                    }
                ]
            }
        },
        "/practice/services": {
            "get": {
                "operationId": "api_v1_practice_services",
                "summary": "Leistungskatalog",
                "tags": [
                    "Praxis"
                ],
                "parameters": [
                    {
                        "name": "includeInactive",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Auch abgelöste Einträge liefern."
                    },
                    {
                        "name": "validOn",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Nur Einträge, die an diesem Tag gelten (JJJJ-MM-TT)."
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        },
                        "description": "Seitengröße."
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Unverändert aus links.next der vorherigen Antwort. Es gibt keinen Offset: er wäre bei nebenläufigen Änderungen falsch."
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Sortierung, kommagetrennt, \"-\" für absteigend. Erlaubt: code, name, createdAt, priceCents. Ein anderes Feld wird mit 422 ABGEWIESEN und nicht ignoriert."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Service"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "practice:read"
                        ]
                    }
                ]
            }
        },
        "/prescriptions": {
            "get": {
                "operationId": "api_v1_prescriptions_index",
                "summary": "Verordnungen auflisten",
                "tags": [
                    "Verordnungen"
                ],
                "parameters": [
                    {
                        "name": "patientId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Auf eine Akte einschränken (ULID)."
                    },
                    {
                        "name": "ongoing",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "true: noch nicht abgeschlossen. false: abgeschlossen."
                    },
                    {
                        "name": "reportDue",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "true: ein Therapiebericht steht an."
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        },
                        "description": "Seitengröße."
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Unverändert aus links.next der vorherigen Antwort. Es gibt keinen Offset: er wäre bei nebenläufigen Änderungen falsch."
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Sortierung, kommagetrennt, \"-\" für absteigend. Erlaubt: issuedOn, createdAt, updatedAt, validUntil, unitCount. Ein anderes Feld wird mit 422 ABGEWIESEN und nicht ignoriert."
                    },
                    {
                        "name": "include",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Verknüpfte Objekte, kommagetrennt: remedies."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Prescription"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "prescriptions:read"
                        ]
                    }
                ]
            }
        },
        "/prescriptions/{prescription}": {
            "get": {
                "operationId": "api_v1_prescriptions_show",
                "summary": "Verordnung lesen",
                "tags": [
                    "Verordnungen"
                ],
                "parameters": [
                    {
                        "name": "prescription",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Prescription"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "prescriptions:read"
                        ]
                    }
                ]
            }
        },
        "/prescriptions/{prescription}/quota": {
            "get": {
                "operationId": "api_v1_prescriptions_quota",
                "summary": "Restkontingent und Berichtsfälligkeit",
                "tags": [
                    "Verordnungen"
                ],
                "parameters": [
                    {
                        "name": "prescription",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/PrescriptionQuota"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "prescriptions:read"
                        ]
                    }
                ]
            }
        },
        "/rooms/occupancy": {
            "get": {
                "operationId": "api_v1_rooms_occupancy",
                "summary": "Raumbelegung abfragen",
                "tags": [
                    "Räume"
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/RoomOccupancy"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "appointments:read"
                        ]
                    }
                ]
            }
        },
        "/tasks": {
            "get": {
                "operationId": "api_v1_tasks_index",
                "summary": "Aufgaben auflisten",
                "tags": [
                    "Aufgaben"
                ],
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Stand, kommagetrennt (open, in_progress, done, cancelled). Ohne Angabe nur open und in_progress."
                    },
                    {
                        "name": "assignee",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "\"me\" (eigene), \"none\" (niemand zuständig) oder die Kennung eines Mitglieds (ULID)."
                    },
                    {
                        "name": "dueBy",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Fällig bis einschließlich diesem Tag (JJJJ-MM-TT); Aufgaben ohne Fälligkeit fallen heraus."
                    },
                    {
                        "name": "patientId",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Auf eine Akte einschränken (ULID). Verlangt patients.view_master_data."
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 25
                        },
                        "description": "Seitengröße."
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Unverändert aus links.next der vorherigen Antwort. Es gibt keinen Offset: er wäre bei nebenläufigen Änderungen falsch."
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Sortierung, kommagetrennt, \"-\" für absteigend. Erlaubt: createdAt, updatedAt. Nicht sortierbar, weil verschlüsselt gespeichert: notes. Ein anderes Feld wird mit 422 ABGEWIESEN und nicht ignoriert."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": [],
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Task"
                                            }
                                        },
                                        "meta": {
                                            "type": "object"
                                        },
                                        "links": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data",
                                        "meta"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "tasks:read"
                        ]
                    }
                ]
            },
            "post": {
                "operationId": "api_v1_tasks_store",
                "summary": "Aufgabe anlegen",
                "tags": [
                    "Aufgaben"
                ],
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "maxLength": 255
                        },
                        "description": "Pflicht. Eine Wiederholung mit demselben Schlüssel liefert die erste Antwort erneut, statt einen zweiten Datensatz anzulegen."
                    }
                ],
                "responses": {
                    "201": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Task"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "tasks:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "title": {
                                        "type": "string",
                                        "maxLength": 120
                                    },
                                    "notes": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 5000
                                    },
                                    "priority": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "enum": [
                                            "low",
                                            "normal",
                                            "high"
                                        ]
                                    },
                                    "dueOn": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "date"
                                    },
                                    "patientId": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "ulid"
                                    },
                                    "assigneeIds": {
                                        "type": [
                                            "array",
                                            "null"
                                        ],
                                        "items": {
                                            "type": "string",
                                            "format": "ulid"
                                        }
                                    }
                                },
                                "required": [
                                    "title"
                                ],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/tasks/{task}": {
            "get": {
                "operationId": "api_v1_tasks_show",
                "summary": "Aufgabe lesen",
                "tags": [
                    "Aufgaben"
                ],
                "parameters": [
                    {
                        "name": "task",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Task"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "tasks:read"
                        ]
                    }
                ]
            },
            "patch": {
                "operationId": "api_v1_tasks_update",
                "summary": "Aufgabe ändern",
                "tags": [
                    "Aufgaben"
                ],
                "parameters": [
                    {
                        "name": "task",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    },
                    {
                        "name": "If-Match",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Pflicht. Das ETag aus dem letzten Lesen. Ohne den Kopfeintrag: 428, bei veraltetem Wert: 412."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Task"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "tasks:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "title": {
                                        "type": "string",
                                        "maxLength": 120
                                    },
                                    "notes": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "maxLength": 5000
                                    },
                                    "priority": {
                                        "type": "string",
                                        "enum": [
                                            "low",
                                            "normal",
                                            "high"
                                        ]
                                    },
                                    "status": {
                                        "type": "string",
                                        "enum": [
                                            "open",
                                            "in_progress",
                                            "done",
                                            "cancelled"
                                        ]
                                    },
                                    "dueOn": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "date"
                                    },
                                    "patientId": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "format": "ulid"
                                    }
                                },
                                "required": [],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            },
            "delete": {
                "operationId": "api_v1_tasks_destroy",
                "summary": "Aufgabe löschen",
                "tags": [
                    "Aufgaben"
                ],
                "parameters": [
                    {
                        "name": "task",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "204": {
                        "description": "Erledigt, kein Rumpf."
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "tasks:write"
                        ]
                    }
                ]
            }
        },
        "/tasks/{task}/assignees": {
            "put": {
                "operationId": "api_v1_tasks_assign",
                "summary": "Zuständige setzen",
                "tags": [
                    "Aufgaben"
                ],
                "parameters": [
                    {
                        "name": "task",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Task"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "tasks:write"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "assigneeIds": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "format": "ulid"
                                        }
                                    }
                                },
                                "required": [],
                                "additionalProperties": false
                            }
                        }
                    }
                }
            }
        },
        "/tasks/{task}/complete": {
            "post": {
                "operationId": "api_v1_tasks_complete",
                "summary": "Aufgabe abhaken",
                "tags": [
                    "Aufgaben"
                ],
                "parameters": [
                    {
                        "name": "task",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Task"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "tasks:write"
                        ]
                    }
                ]
            }
        },
        "/tasks/{task}/reopen": {
            "post": {
                "operationId": "api_v1_tasks_reopen",
                "summary": "Aufgabe wieder öffnen",
                "tags": [
                    "Aufgaben"
                ],
                "parameters": [
                    {
                        "name": "task",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Öffentliche Kennung (ULID)."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Erfolg.",
                        "headers": {
                            "ETag": {
                                "description": "Stand des Datensatzes. Beim Schreiben als If-Match zurückgeben.",
                                "schema": {
                                    "type": "string"
                                }
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "$ref": "#/components/schemas/Task"
                                        },
                                        "meta": {
                                            "type": "object"
                                        }
                                    },
                                    "required": [
                                        "data"
                                    ]
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Fehlender Pflicht-Kopfeintrag, etwa Idempotency-Key.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Kein gültiges Token.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Umfang des Tokens oder Berechtigung des Kontos reicht nicht.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Nicht vorhanden - auch dann, wenn die Kennung zu einer anderen Praxis gehört.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Fachlicher Konflikt (Terminkollision, ausgeschöpftes Kontingent, Idempotenzschlüssel).",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "412": {
                        "description": "If-Match passt nicht mehr: der Datensatz wurde zwischenzeitlich geändert.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Eingabe oder Abfrageparameter nicht annehmbar.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "428": {
                        "description": "If-Match fehlt.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Ratenbegrenzung je Token oder je Praxis greift.",
                        "content": {
                            "application/problem+json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Problem"
                                }
                            }
                        }
                    }
                },
                "security": [
                    {
                        "bearerAuth": [
                            "tasks:write"
                        ]
                    }
                ]
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "description": "Ein persönliches Zugangstoken. Es gehört zu genau einer Praxis; die Praxis wird daraus gelesen und steht nie in der URL."
            }
        },
        "schemas": {
            "AccessLogEntry": {
                "type": "object",
                "properties": {
                    "occurredAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Zeitpunkt an der Tür."
                    },
                    "recordedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Zeitpunkt des Eingangs hier. Nach einer Netzstörung liegt er deutlich später."
                    },
                    "personId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Öffentliche Kennung der Person, sofern die Steuerung eine erkannt hat."
                    },
                    "credentialType": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "pin",
                            "nfc"
                        ]
                    },
                    "area": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Schlüssel des Bereichs, wie im Schnappschuss."
                    },
                    "result": {
                        "type": "string",
                        "enum": [
                            "granted",
                            "denied"
                        ]
                    },
                    "reason": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "required": [
                    "occurredAt",
                    "recordedAt",
                    "personId",
                    "credentialType",
                    "area",
                    "result",
                    "reason"
                ],
                "additionalProperties": false
            },
            "AccessSnapshot": {
                "type": "object",
                "properties": {
                    "version": {
                        "type": "integer",
                        "description": "Fassung des Formats. Steigt, wenn sich die Bedeutung eines Feldes ändert - nicht, wenn eines dazukommt."
                    },
                    "generatedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Zeitpunkt des Abrufs."
                    },
                    "areas": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "key": {
                                    "type": "string",
                                    "description": "Der Schlüssel, der an den Personen steht. Er ändert sich nie; die Bezeichnung schon."
                                },
                                "label": {
                                    "type": "string"
                                },
                                "pinRule": {
                                    "type": "string",
                                    "enum": [
                                        "standard",
                                        "nuki"
                                    ],
                                    "description": "Welches Tastenfeld an diesem Bereich hängt: \"nuki\" nimmt nur sechs Ziffern ohne Null an, die nicht mit 12 beginnen."
                                }
                            },
                            "required": [
                                "key",
                                "label",
                                "pinRule"
                            ],
                            "additionalProperties": false
                        },
                        "description": "Die Bereiche der Praxis. Kennt die Steuerung einen Schlüssel nicht, öffnet er dort nichts."
                    },
                    "persons": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "string",
                                    "description": "Öffentliche Kennung der Person. Dieselbe Kennung meldet die Gebäudesteuerung im Protokoll zurück."
                                },
                                "name": {
                                    "type": "string"
                                },
                                "active": {
                                    "type": "boolean",
                                    "description": "Ausgeschaltete Personen stehen weiterhin im Stand - mit false und ohne Zugangsmittel. Weggelassen wären sie nicht unterscheidbar von \"gelöscht\"."
                                },
                                "validFrom": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "format": "date",
                                    "description": "Leer heisst \"ohne Grenze\"."
                                },
                                "validUntil": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "format": "date",
                                    "description": "Leer heisst \"ohne Grenze\"."
                                },
                                "weekdays": {
                                    "type": "array",
                                    "items": {
                                        "type": "string",
                                        "enum": [
                                            "mon",
                                            "tue",
                                            "wed",
                                            "thu",
                                            "fri",
                                            "sat",
                                            "sun"
                                        ]
                                    },
                                    "description": "Leere Liste heisst \"an jedem Tag\"."
                                },
                                "timeFrom": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "description": "HH:MM. Leer heisst \"ohne Grenze\"."
                                },
                                "timeUntil": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "description": "HH:MM. Leer heisst \"ohne Grenze\"."
                                },
                                "areas": {
                                    "type": "array",
                                    "items": {
                                        "type": "string"
                                    },
                                    "description": "Whitelist aus Schlüsseln der Bereiche (siehe \"areas\" oben). Eine leere Liste heisst \"kein Bereich\" und nicht \"alle\"."
                                },
                                "credentials": {
                                    "type": "array",
                                    "items": {
                                        "type": "object",
                                        "properties": {
                                            "type": {
                                                "type": "string",
                                                "enum": [
                                                    "pin",
                                                    "nfc"
                                                ]
                                            },
                                            "value": {
                                                "type": "string",
                                                "description": "Der Code im Klartext."
                                            },
                                            "label": {
                                                "type": [
                                                    "string",
                                                    "null"
                                                ]
                                            }
                                        },
                                        "required": [
                                            "type",
                                            "value",
                                            "label"
                                        ],
                                        "additionalProperties": false
                                    },
                                    "description": "Auch mehrere derselben Art - jedes öffnet. Bei einer ausgeschalteten Person leer: Die Codes bleiben gespeichert, werden aber nicht ausgeliefert."
                                }
                            },
                            "required": [
                                "id",
                                "name",
                                "active",
                                "validFrom",
                                "validUntil",
                                "weekdays",
                                "timeFrom",
                                "timeUntil",
                                "areas",
                                "credentials"
                            ],
                            "additionalProperties": false
                        }
                    }
                },
                "required": [
                    "version",
                    "generatedAt",
                    "areas",
                    "persons"
                ],
                "additionalProperties": false
            },
            "Account": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "firstName": {
                        "type": "string"
                    },
                    "lastName": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string"
                    },
                    "emailVerified": {
                        "type": "boolean"
                    },
                    "practice": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string",
                                "format": "ulid",
                                "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                            },
                            "name": {
                                "type": "string"
                            },
                            "accentColor": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Akzentfarbe der Praxis (#rrggbb) oder null für die Vorgabe. Der Client wählt Schrift und Flächen daraus selbst kontrastsicher."
                            }
                        },
                        "required": [
                            "id",
                            "name",
                            "accentColor"
                        ],
                        "additionalProperties": false,
                        "description": "Die Praxis, an die das verwendete Token gebunden ist."
                    },
                    "role": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "owner",
                            "management",
                            "therapist",
                            "reception",
                            "billing",
                            "assistant"
                        ]
                    },
                    "roleLabel": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "permissions": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "description": "Die Berechtigungen des Kontos in dieser Praxis."
                    },
                    "tokenScopes": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "description": "Der Umfang des verwendeten Tokens. Er kann die Berechtigungen nur einschränken, nie erweitern."
                    }
                },
                "required": [
                    "id",
                    "firstName",
                    "lastName",
                    "email",
                    "emailVerified",
                    "practice",
                    "role",
                    "roleLabel",
                    "permissions",
                    "tokenScopes"
                ],
                "additionalProperties": false
            },
            "ApiToken": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "Kennung des Tokens."
                    },
                    "name": {
                        "type": "string"
                    },
                    "deviceName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "abilities": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "lastUsedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "expiresAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "createdAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "current": {
                        "type": "boolean",
                        "description": "Das Token, mit dem diese Anfrage kam."
                    },
                    "token": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Der Klartext - AUSSCHLIESSLICH in der Antwort auf das Anlegen. Danach ist er nicht mehr abrufbar, weil nur sein Hash gespeichert wird."
                    }
                },
                "required": [
                    "id",
                    "name",
                    "deviceName",
                    "abilities",
                    "lastUsedAt",
                    "expiresAt",
                    "createdAt",
                    "current"
                ],
                "additionalProperties": false
            },
            "Appointment": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "startsAt": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "endsAt": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "blockedFrom": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Beginn inklusive Vorbereitungszeit."
                    },
                    "blockedUntil": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Ende inklusive Nachbereitungszeit."
                    },
                    "durationMinutes": {
                        "type": "integer"
                    },
                    "preparationMinutes": {
                        "type": "integer"
                    },
                    "followUpMinutes": {
                        "type": "integer"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "scheduled",
                            "confirmed",
                            "attended",
                            "no_show",
                            "cancelled"
                        ]
                    },
                    "statusLabel": {
                        "type": "string"
                    },
                    "title": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "isSeriesException": {
                        "type": "boolean"
                    },
                    "seriesId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "seriesSequence": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "cancelledAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "patient": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string",
                                "format": "ulid",
                                "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                            },
                            "lastName": {
                                "type": "string"
                            },
                            "firstName": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "lastName",
                            "firstName"
                        ],
                        "additionalProperties": false,
                        "description": "Fehlt bei Terminen ohne Patientenbezug (Besprechung, Sperrzeit)."
                    },
                    "type": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string",
                                "format": "ulid",
                                "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                            },
                            "name": {
                                "type": "string"
                            },
                            "color": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "id",
                            "name",
                            "color"
                        ],
                        "additionalProperties": false
                    },
                    "practitioner": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string",
                                "format": "ulid",
                                "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name"
                        ],
                        "additionalProperties": false
                    },
                    "room": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string",
                                "format": "ulid",
                                "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name"
                        ],
                        "additionalProperties": false
                    },
                    "clinical": {
                        "type": "object",
                        "properties": {
                            "treatmentNote": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "internalNote": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "cancellationReason": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "cancellationReasonCode": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "enum": [
                                    "patient_cancelled",
                                    "patient_sick",
                                    "patient_no_show",
                                    "rescheduled",
                                    "practice_cancelled",
                                    "practitioner_sick",
                                    "prescription_expired",
                                    "other"
                                ],
                                "description": "Der eingeordnete Absagegrund - das Feld, worüber sich Absagen auswerten lassen. null bei jedem Termin ohne Absage und bei älteren Absagen, die nur den Freitext tragen."
                            }
                        },
                        "required": [
                            "treatmentNote",
                            "internalNote",
                            "cancellationReason",
                            "cancellationReasonCode"
                        ],
                        "additionalProperties": false,
                        "description": "Nur mit Zugriff auf die Behandlungsdaten dieses Termins: clinical.view, oder clinical.view_own_only an einem Termin, den das Konto selbst hält."
                    },
                    "createdAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "updatedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    }
                },
                "required": [
                    "id",
                    "startsAt",
                    "endsAt",
                    "blockedFrom",
                    "blockedUntil",
                    "durationMinutes",
                    "preparationMinutes",
                    "followUpMinutes",
                    "status",
                    "statusLabel",
                    "title",
                    "isSeriesException",
                    "seriesId",
                    "seriesSequence",
                    "cancelledAt",
                    "createdAt",
                    "updatedAt"
                ],
                "additionalProperties": false
            },
            "AppointmentType": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "name": {
                        "type": "string"
                    },
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "color": {
                        "type": "string",
                        "description": "Farbe im Kalender, als #rrggbb."
                    },
                    "durationMinutes": {
                        "type": "integer",
                        "description": "Vorgabedauer. Ein einzelner Termin darf davon abweichen."
                    },
                    "preparationMinutes": {
                        "type": "integer",
                        "description": "Rüstzeit VOR dem Termin. Belegt Raum und Behandler mit, steht aber nicht in starts_at - deshalb ist die Sperre im Kalender länger als die Behandlung."
                    },
                    "followUpMinutes": {
                        "type": "integer",
                        "description": "Rüstzeit NACH dem Termin."
                    },
                    "requiresPatient": {
                        "type": "boolean",
                        "description": "Ohne Akte lässt sich ein Termin dieser Art nicht anlegen."
                    },
                    "requiresRoom": {
                        "type": "boolean"
                    },
                    "onlineBookable": {
                        "type": "boolean",
                        "description": "Ob die Praxis diese Art zur Selbstbuchung freigegeben hat. Eine Buchungsoberfläche für Patient:innen zeigt nur, was hier true ist."
                    },
                    "absenceKind": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Gesetzt heisst: Sperre im Kalender (Pause, Besprechung, Urlaub) und keine buchbare Leistung. Leer heisst: gewöhnliche Terminart. Nicht am Namen erkennen - der ist frei änderbar."
                    },
                    "active": {
                        "type": "boolean",
                        "description": "Stillgelegte Arten stehen nur mit ?includeInactive=true in der Liste. Bestehende Termine tragen sie weiterhin."
                    }
                },
                "required": [
                    "id",
                    "name",
                    "description",
                    "color",
                    "durationMinutes",
                    "preparationMinutes",
                    "followUpMinutes",
                    "requiresPatient",
                    "requiresRoom",
                    "onlineBookable",
                    "absenceKind",
                    "active"
                ],
                "additionalProperties": false
            },
            "Consent": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "purpose": {
                        "type": "string",
                        "enum": [
                            "appointment_reminder",
                            "invoice_delivery",
                            "document_delivery",
                            "practice_notice"
                        ]
                    },
                    "purposeLabel": {
                        "type": "string"
                    },
                    "channel": {
                        "type": "string",
                        "enum": [
                            "sms",
                            "email",
                            "whatsapp"
                        ]
                    },
                    "channelLabel": {
                        "type": "string"
                    },
                    "grantedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "revokedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "active": {
                        "type": "boolean"
                    },
                    "revocationNote": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "required": [
                    "id",
                    "purpose",
                    "purposeLabel",
                    "channel",
                    "channelLabel",
                    "grantedAt",
                    "revokedAt",
                    "active",
                    "revocationNote"
                ],
                "additionalProperties": false
            },
            "Document": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Kennung des erzeugenden Datensatzes."
                    },
                    "kind": {
                        "type": "string",
                        "enum": [
                            "invoice",
                            "dunningNotice",
                            "prescription"
                        ],
                        "description": "Woher der Beleg stammt."
                    },
                    "kindLabel": {
                        "type": "string"
                    },
                    "title": {
                        "type": "string"
                    },
                    "issuedOn": {
                        "type": "string",
                        "format": "date"
                    },
                    "mediaType": {
                        "type": "string"
                    },
                    "sha256": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Fingerabdruck der abgelegten Datei."
                    },
                    "downloadPath": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Pfad zum Abruf, sofern die Schnittstelle den Beleg ausliefert."
                    }
                },
                "required": [
                    "id",
                    "kind",
                    "kindLabel",
                    "title",
                    "issuedOn",
                    "mediaType",
                    "sha256",
                    "downloadPath"
                ],
                "additionalProperties": false
            },
            "FileUpload": {
                "type": "object",
                "properties": {
                    "url": {
                        "type": "string",
                        "description": "Vorsignierte Adresse im Objektspeicher."
                    },
                    "method": {
                        "type": "string",
                        "enum": [
                            "PUT"
                        ]
                    },
                    "headers": {
                        "type": "object",
                        "properties": {
                            "Content-Type": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "Content-Type"
                        ],
                        "additionalProperties": false,
                        "description": "Genau so mitschicken - Typ und Länge stehen in der Unterschrift."
                    },
                    "upload": {
                        "type": "string",
                        "description": "Versiegelter Beleg für den Abschluss (POST patients/{id}/files)."
                    },
                    "expiresAt": {
                        "type": "string",
                        "format": "date-time"
                    }
                },
                "required": [
                    "url",
                    "method",
                    "headers",
                    "upload",
                    "expiresAt"
                ],
                "additionalProperties": false
            },
            "FreeSlot": {
                "type": "object",
                "properties": {
                    "startsAt": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "endsAt": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "blockedFrom": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "blockedUntil": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "durationMinutes": {
                        "type": "integer"
                    },
                    "practitionerId": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "roomId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    }
                },
                "required": [
                    "startsAt",
                    "endsAt",
                    "blockedFrom",
                    "blockedUntil",
                    "durationMinutes",
                    "practitionerId",
                    "roomId"
                ],
                "additionalProperties": false
            },
            "Invoice": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "number": {
                        "type": "string",
                        "description": "Die Rechnungsnummer, oder \"(Entwurf)\"."
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "private_patient",
                            "statutory_clearing"
                        ]
                    },
                    "typeLabel": {
                        "type": "string"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "draft",
                            "open",
                            "paid",
                            "dunned",
                            "cancelled"
                        ]
                    },
                    "statusLabel": {
                        "type": "string"
                    },
                    "patientId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "issuedOn": {
                        "type": "string",
                        "format": "date"
                    },
                    "dueOn": {
                        "type": "string",
                        "format": "date"
                    },
                    "daysOverdue": {
                        "type": "integer"
                    },
                    "totalNetCents": {
                        "type": "integer",
                        "description": "Betrag in Cent."
                    },
                    "totalTaxCents": {
                        "type": "integer",
                        "description": "Betrag in Cent."
                    },
                    "totalGrossCents": {
                        "type": "integer",
                        "description": "Betrag in Cent."
                    },
                    "dunningFeesCents": {
                        "type": "integer",
                        "description": "Betrag in Cent."
                    },
                    "paidAmountCents": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Betrag in Cent."
                    },
                    "outstandingCents": {
                        "type": "integer",
                        "description": "Betrag in Cent."
                    },
                    "paidAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "cancelledAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "dunningLevel": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "reminder",
                            "first",
                            "second"
                        ]
                    },
                    "hasDocument": {
                        "type": "boolean"
                    },
                    "items": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "string",
                                    "format": "ulid",
                                    "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                                },
                                "kind": {
                                    "type": "string",
                                    "enum": [
                                        "service",
                                        "remedy",
                                        "copayment",
                                        "missed_appointment"
                                    ]
                                },
                                "kindLabel": {
                                    "type": "string"
                                },
                                "code": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "name": {
                                    "type": "string"
                                },
                                "unit": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "performedOn": {
                                    "type": "string",
                                    "format": "date"
                                },
                                "quantity": {
                                    "type": "integer"
                                },
                                "unitPriceCents": {
                                    "type": "integer",
                                    "description": "Betrag in Cent."
                                },
                                "taxRate": {
                                    "type": "integer",
                                    "description": "Basispunkte, 1900 = 19,00 %."
                                },
                                "netCents": {
                                    "type": "integer",
                                    "description": "Betrag in Cent."
                                },
                                "taxCents": {
                                    "type": "integer",
                                    "description": "Betrag in Cent."
                                },
                                "grossCents": {
                                    "type": "integer",
                                    "description": "Betrag in Cent."
                                }
                            },
                            "required": [
                                "id",
                                "kind",
                                "kindLabel",
                                "code",
                                "name",
                                "unit",
                                "performedOn",
                                "quantity",
                                "unitPriceCents",
                                "taxRate",
                                "netCents",
                                "taxCents",
                                "grossCents"
                            ],
                            "additionalProperties": false
                        },
                        "description": "Nur mit include=items."
                    },
                    "createdAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "updatedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    }
                },
                "required": [
                    "id",
                    "number",
                    "type",
                    "typeLabel",
                    "status",
                    "statusLabel",
                    "patientId",
                    "issuedOn",
                    "dueOn",
                    "daysOverdue",
                    "totalNetCents",
                    "totalTaxCents",
                    "totalGrossCents",
                    "dunningFeesCents",
                    "paidAmountCents",
                    "outstandingCents",
                    "paidAt",
                    "cancelledAt",
                    "dunningLevel",
                    "hasDocument",
                    "createdAt",
                    "updatedAt"
                ],
                "additionalProperties": false
            },
            "LoginStep": {
                "type": "object",
                "properties": {
                    "status": {
                        "type": "string",
                        "enum": [
                            "authenticated",
                            "twoFactorRequired",
                            "practiceRequired"
                        ],
                        "description": "authenticated: token steht bereit. twoFactorRequired: Code an auth/two-factor schicken. practiceRequired: eine der practices wählen und mit challenge an auth/two-factor schicken."
                    },
                    "challenge": {
                        "type": "string",
                        "description": "Versiegelte Zwischenstufe, wenige Minuten gültig."
                    },
                    "expiresAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Ablauf der Zwischenstufe."
                    },
                    "practices": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "string",
                                    "format": "ulid",
                                    "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                                },
                                "name": {
                                    "type": "string"
                                }
                            },
                            "required": [
                                "id",
                                "name"
                            ],
                            "additionalProperties": false
                        }
                    },
                    "token": {
                        "type": "string",
                        "description": "Nur einmal zu sehen. Gehört ins sichere Speicherfach des Geräts."
                    },
                    "tokenId": {
                        "type": "string",
                        "description": "Kennung zum Widerruf (DELETE account/tokens/{token})."
                    },
                    "practice": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string",
                                "format": "ulid",
                                "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name"
                        ],
                        "additionalProperties": false
                    }
                },
                "required": [
                    "status"
                ],
                "additionalProperties": false
            },
            "Member": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Kennung des Kontos."
                    },
                    "firstName": {
                        "type": "string"
                    },
                    "lastName": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string"
                    },
                    "role": {
                        "type": "string",
                        "enum": [
                            "owner",
                            "management",
                            "therapist",
                            "reception",
                            "billing",
                            "assistant"
                        ]
                    },
                    "roleLabel": {
                        "type": "string"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "invited",
                            "active",
                            "suspended",
                            "left"
                        ]
                    },
                    "statusLabel": {
                        "type": "string"
                    },
                    "treatsPatients": {
                        "type": "boolean"
                    },
                    "joinedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    }
                },
                "required": [
                    "id",
                    "firstName",
                    "lastName",
                    "email",
                    "role",
                    "roleLabel",
                    "status",
                    "statusLabel",
                    "treatsPatients",
                    "joinedAt"
                ],
                "additionalProperties": false
            },
            "Notification": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "kind": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "task",
                            "time_tracking",
                            "employment",
                            "message",
                            "mention",
                            "appointment",
                            "bounce",
                            "consent",
                            "whatsapp",
                            "import",
                            "support",
                            "prices",
                            "sms_quota",
                            "storage_quota",
                            "auto_top_up",
                            "call",
                            "malware",
                            "data_request"
                        ]
                    },
                    "kindLabel": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "title": {
                        "type": "string"
                    },
                    "body": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Reiner Text, ohne Auszeichnung."
                    },
                    "readAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "createdAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    }
                },
                "required": [
                    "id",
                    "kind",
                    "kindLabel",
                    "title",
                    "body",
                    "readAt",
                    "createdAt"
                ],
                "additionalProperties": false
            },
            "NotificationReadState": {
                "type": "object",
                "properties": {
                    "marked": {
                        "type": "integer"
                    },
                    "unread": {
                        "type": "integer"
                    }
                },
                "required": [
                    "marked",
                    "unread"
                ],
                "additionalProperties": false
            },
            "OpeningHour": {
                "type": "object",
                "properties": {
                    "locationId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "weekday": {
                        "type": "integer",
                        "description": "ISO-8601: 1 = Montag ... 7 = Sonntag."
                    },
                    "weekdayLabel": {
                        "type": "string"
                    },
                    "opensAt": {
                        "type": "string"
                    },
                    "closesAt": {
                        "type": "string"
                    },
                    "breakStartsAt": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "breakEndsAt": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "note": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "slots": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "from": {
                                    "type": "string"
                                },
                                "to": {
                                    "type": "string"
                                }
                            },
                            "required": [
                                "from",
                                "to"
                            ],
                            "additionalProperties": false
                        },
                        "description": "Der Tag ohne Pause, fertig zerlegt."
                    }
                },
                "required": [
                    "locationId",
                    "weekday",
                    "weekdayLabel",
                    "opensAt",
                    "closesAt",
                    "breakStartsAt",
                    "breakEndsAt",
                    "note",
                    "slots"
                ],
                "additionalProperties": false
            },
            "Patient": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "lastName": {
                        "type": "string"
                    },
                    "firstName": {
                        "type": "string"
                    },
                    "gender": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "M",
                            "F",
                            "D"
                        ]
                    },
                    "genderLabel": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "birthDate": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "age": {
                        "type": [
                            "integer",
                            "null"
                        ]
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "active",
                            "inactive",
                            "archived",
                            "merged"
                        ]
                    },
                    "statusLabel": {
                        "type": "string"
                    },
                    "guardian": {
                        "type": "object",
                        "properties": {
                            "firstName": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "lastName": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "gender": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "firstName",
                            "lastName",
                            "gender"
                        ],
                        "additionalProperties": false
                    },
                    "insurance": {
                        "type": "object",
                        "properties": {
                            "provider": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "type": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "typeLabel": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "provider",
                            "type",
                            "typeLabel"
                        ],
                        "additionalProperties": false
                    },
                    "contact": {
                        "type": "object",
                        "properties": {
                            "phone": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "mobile": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "email": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "phone",
                            "mobile",
                            "email"
                        ],
                        "additionalProperties": false
                    },
                    "address": {
                        "type": "object",
                        "properties": {
                            "street": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "postalCode": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "city": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "street",
                            "postalCode",
                            "city"
                        ],
                        "additionalProperties": false
                    },
                    "clinical": {
                        "type": "object",
                        "properties": {
                            "doctor": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "diagnosis": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "anamnesis": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "notes": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            }
                        },
                        "required": [
                            "doctor",
                            "diagnosis",
                            "anamnesis",
                            "notes"
                        ],
                        "additionalProperties": false,
                        "description": "Nur mit Zugriff auf die Behandlungsdaten dieser Akte: clinical.view, oder clinical.view_own_only bei einer Patientin, die das Konto behandelt. Fehlt er, fehlt der ganze Block. Anamnese und Notizen kommen als reiner Text, auch wenn sie in der Praxis mit Formatierung geschrieben wurden."
                    },
                    "mergedIntoId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "createdAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "updatedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "consents": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "string",
                                    "format": "ulid",
                                    "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                                },
                                "purpose": {
                                    "type": "string",
                                    "enum": [
                                        "appointment_reminder",
                                        "invoice_delivery",
                                        "document_delivery",
                                        "practice_notice"
                                    ]
                                },
                                "purposeLabel": {
                                    "type": "string"
                                },
                                "channel": {
                                    "type": "string",
                                    "enum": [
                                        "sms",
                                        "email",
                                        "whatsapp"
                                    ]
                                },
                                "channelLabel": {
                                    "type": "string"
                                },
                                "grantedAt": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "format": "date-time"
                                },
                                "revokedAt": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "format": "date-time"
                                },
                                "active": {
                                    "type": "boolean"
                                },
                                "revocationNote": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                }
                            },
                            "required": [
                                "id",
                                "purpose",
                                "purposeLabel",
                                "channel",
                                "channelLabel",
                                "grantedAt",
                                "revokedAt",
                                "active",
                                "revocationNote"
                            ],
                            "additionalProperties": false
                        },
                        "description": "Nur mit include=consents."
                    }
                },
                "required": [
                    "id",
                    "lastName",
                    "firstName",
                    "gender",
                    "genderLabel",
                    "birthDate",
                    "age",
                    "status",
                    "statusLabel",
                    "guardian",
                    "insurance",
                    "contact",
                    "address",
                    "mergedIntoId",
                    "createdAt",
                    "updatedAt"
                ],
                "additionalProperties": false
            },
            "PatientFile": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "title": {
                        "type": "string"
                    },
                    "category": {
                        "type": "string",
                        "enum": [
                            "doctor_letter",
                            "prescription",
                            "finding",
                            "certificate",
                            "consent",
                            "photo",
                            "correspondence",
                            "other"
                        ]
                    },
                    "categoryLabel": {
                        "type": "string"
                    },
                    "issuedOn": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "mediaType": {
                        "type": "string"
                    },
                    "sizeBytes": {
                        "type": "integer"
                    },
                    "scanStatus": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "ausstehend",
                            "sauber",
                            "quarantaene",
                            "abgelehnt",
                            "fehler",
                            "geloescht"
                        ],
                        "description": "Ergebnis der Virenprüfung. Nur \"sauber\" (oder null bei altem Bestand) ist abrufbar; \"ausstehend\" heißt \"wird geprüft\"."
                    },
                    "scanStatusLabel": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "available": {
                        "type": "boolean",
                        "description": "Darf die Datei ausgeliefert werden?"
                    },
                    "uploadedByPatient": {
                        "type": "boolean"
                    },
                    "createdAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    }
                },
                "required": [
                    "id",
                    "title",
                    "category",
                    "categoryLabel",
                    "issuedOn",
                    "mediaType",
                    "sizeBytes",
                    "scanStatus",
                    "scanStatusLabel",
                    "available",
                    "uploadedByPatient",
                    "createdAt"
                ],
                "additionalProperties": false
            },
            "Practice": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "name": {
                        "type": "string"
                    },
                    "email": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "phone": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "address": {
                        "type": "object",
                        "properties": {
                            "street": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "houseNumber": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "postalCode": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "city": {
                                "type": [
                                    "string",
                                    "null"
                                ]
                            },
                            "countryCode": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "street",
                            "houseNumber",
                            "postalCode",
                            "city",
                            "countryCode"
                        ],
                        "additionalProperties": false
                    },
                    "locations": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "string",
                                    "format": "ulid",
                                    "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                                },
                                "name": {
                                    "type": "string"
                                },
                                "street": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "houseNumber": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "postalCode": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "city": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "phone": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "email": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "isPrimary": {
                                    "type": "boolean"
                                },
                                "isActive": {
                                    "type": "boolean"
                                }
                            },
                            "required": [
                                "id",
                                "name",
                                "street",
                                "houseNumber",
                                "postalCode",
                                "city",
                                "phone",
                                "email",
                                "isPrimary",
                                "isActive"
                            ],
                            "additionalProperties": false
                        }
                    },
                    "createdAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    }
                },
                "required": [
                    "id",
                    "name",
                    "email",
                    "phone",
                    "address",
                    "locations",
                    "createdAt"
                ],
                "additionalProperties": false
            },
            "Prescription": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "statutory",
                            "private",
                            "accident",
                            "dental",
                            "aid",
                            "self_pay"
                        ]
                    },
                    "typeLabel": {
                        "type": "string"
                    },
                    "patientId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "doctor": {
                        "type": "string"
                    },
                    "doctorLanr": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "payerName": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "payerIk": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "issuedOn": {
                        "type": "string",
                        "format": "date"
                    },
                    "receivedOn": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "diagnosisCode": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Fehlt ohne Zugriff auf die Behandlungsdaten dieser Verordnung."
                    },
                    "diagnosisGroup": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Fehlt ohne Zugriff auf die Behandlungsdaten dieser Verordnung."
                    },
                    "remedy": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "frequency": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "treatmentStartBy": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "validUntil": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "billingDeadlineOn": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "billingDeadlinePassed": {
                        "type": "boolean"
                    },
                    "homeVisit": {
                        "type": "boolean"
                    },
                    "longTermNeed": {
                        "type": "boolean"
                    },
                    "completedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "quota": {
                        "type": "object",
                        "properties": {
                            "prescribed": {
                                "type": "integer"
                            },
                            "used": {
                                "type": "integer"
                            },
                            "remaining": {
                                "type": "integer",
                                "description": "Nie negativ."
                            },
                            "exceeded": {
                                "type": "boolean",
                                "description": "Mehr behandelt als verordnet."
                            },
                            "exhausted": {
                                "type": "boolean"
                            }
                        },
                        "required": [
                            "prescribed",
                            "used",
                            "remaining",
                            "exceeded",
                            "exhausted"
                        ],
                        "additionalProperties": false
                    },
                    "report": {
                        "type": "object",
                        "properties": {
                            "required": {
                                "type": "boolean"
                            },
                            "dueAfterUnits": {
                                "type": "integer"
                            },
                            "due": {
                                "type": "boolean"
                            },
                            "finalized": {
                                "type": "boolean"
                            }
                        },
                        "required": [
                            "required",
                            "dueAfterUnits",
                            "due",
                            "finalized"
                        ],
                        "additionalProperties": false
                    },
                    "copayment": {
                        "type": "object",
                        "properties": {
                            "required": {
                                "type": "boolean"
                            },
                            "exempt": {
                                "type": "boolean"
                            },
                            "status": {
                                "type": "string",
                                "enum": [
                                    "not_required",
                                    "exempt",
                                    "open",
                                    "partially_paid",
                                    "paid"
                                ]
                            },
                            "statusLabel": {
                                "type": "string"
                            },
                            "amountCents": {
                                "type": [
                                    "integer",
                                    "null"
                                ],
                                "description": "Betrag in Cent."
                            },
                            "paidCents": {
                                "type": "integer",
                                "description": "Betrag in Cent."
                            },
                            "outstandingCents": {
                                "type": "integer",
                                "description": "Betrag in Cent."
                            }
                        },
                        "required": [
                            "required",
                            "exempt",
                            "status",
                            "statusLabel",
                            "amountCents",
                            "paidCents",
                            "outstandingCents"
                        ],
                        "additionalProperties": false
                    },
                    "remedies": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "positionNumber": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                },
                                "name": {
                                    "type": "string"
                                },
                                "kind": {
                                    "type": "string",
                                    "enum": [
                                        "primary",
                                        "optional",
                                        "supplementary",
                                        "combination"
                                    ]
                                },
                                "kindLabel": {
                                    "type": "string"
                                },
                                "quantity": {
                                    "type": "integer"
                                },
                                "frequency": {
                                    "type": [
                                        "string",
                                        "null"
                                    ]
                                }
                            },
                            "required": [
                                "positionNumber",
                                "name",
                                "kind",
                                "kindLabel",
                                "quantity",
                                "frequency"
                            ],
                            "additionalProperties": false
                        },
                        "description": "Nur mit include=remedies."
                    },
                    "createdAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "updatedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    }
                },
                "required": [
                    "id",
                    "type",
                    "typeLabel",
                    "patientId",
                    "doctor",
                    "doctorLanr",
                    "payerName",
                    "payerIk",
                    "issuedOn",
                    "receivedOn",
                    "remedy",
                    "frequency",
                    "treatmentStartBy",
                    "validUntil",
                    "billingDeadlineOn",
                    "billingDeadlinePassed",
                    "homeVisit",
                    "longTermNeed",
                    "completedAt",
                    "quota",
                    "report",
                    "copayment",
                    "createdAt",
                    "updatedAt"
                ],
                "additionalProperties": false
            },
            "PrescriptionQuota": {
                "type": "object",
                "properties": {
                    "prescriptionId": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "prescribed": {
                        "type": "integer"
                    },
                    "used": {
                        "type": "integer"
                    },
                    "remaining": {
                        "type": "integer"
                    },
                    "exceeded": {
                        "type": "boolean"
                    },
                    "exhausted": {
                        "type": "boolean"
                    },
                    "reportRequired": {
                        "type": "boolean"
                    },
                    "reportDueAfterUnits": {
                        "type": "integer"
                    },
                    "reportDue": {
                        "type": "boolean"
                    },
                    "reportFinalized": {
                        "type": "boolean"
                    },
                    "completedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "billingDeadlineOn": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "billingDeadlinePassed": {
                        "type": "boolean"
                    }
                },
                "required": [
                    "prescriptionId",
                    "prescribed",
                    "used",
                    "remaining",
                    "exceeded",
                    "exhausted",
                    "reportRequired",
                    "reportDueAfterUnits",
                    "reportDue",
                    "reportFinalized",
                    "completedAt",
                    "billingDeadlineOn",
                    "billingDeadlinePassed"
                ],
                "additionalProperties": false
            },
            "Problem": {
                "type": "object",
                "description": "Fehlerbeschreibung nach RFC 9457. \"type\" ist die stabile Kennung der Fehlerart - danach verzweigt ein Client, nicht nach der Meldung.",
                "properties": {
                    "type": {
                        "type": "string",
                        "format": "uri"
                    },
                    "title": {
                        "type": "string"
                    },
                    "status": {
                        "type": "integer"
                    },
                    "detail": {
                        "type": "string"
                    },
                    "instance": {
                        "type": "string"
                    }
                },
                "required": [
                    "type",
                    "title",
                    "status"
                ],
                "additionalProperties": true
            },
            "RoomOccupancy": {
                "type": "object",
                "properties": {
                    "generatedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Zeitpunkt der Erhebung. Alle Angaben beziehen sich auf ihn."
                    },
                    "rooms": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "string",
                                    "format": "ulid",
                                    "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                                },
                                "name": {
                                    "type": "string",
                                    "description": "Bezeichnung des Raums, wie die Praxis sie führt."
                                },
                                "occupied": {
                                    "type": "boolean",
                                    "description": "Läuft in diesem Raum gerade eine Belegung? Gezählt wird der Zeitraum einschließlich Vor- und Nachbereitung - also genau das, was auch die Konfliktprüfung als belegt ansieht. Abgesagte Termine zählen nicht."
                                },
                                "until": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "format": "date-time",
                                    "description": "Ende der laufenden Belegung, null bei freiem Raum. Bei zwei sich überschneidenden Terminen das spätere Ende."
                                },
                                "nextStart": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "format": "date-time",
                                    "description": "Beginn der nächsten Belegung an DIESEM Tag, null wenn heute keine mehr folgt. Bewusst auf den laufenden Tag begrenzt: ein Wert von übermorgen taugt für keine Vorheizregel."
                                }
                            },
                            "required": [
                                "id",
                                "name",
                                "occupied",
                                "until",
                                "nextStart"
                            ],
                            "additionalProperties": false
                        },
                        "description": "Alle AKTIVEN Räume der Praxis - auch die freien. Ein Raum, der stillschweigend fehlte, ließe sich von einem freien nicht unterscheiden."
                    }
                },
                "required": [
                    "generatedAt",
                    "rooms"
                ],
                "additionalProperties": false
            },
            "Service": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "code": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "name": {
                        "type": "string"
                    },
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "unit": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "unitPriceCents": {
                        "type": "integer",
                        "description": "Nettopreis in Cent."
                    },
                    "taxRate": {
                        "type": "integer",
                        "description": "Basispunkte, 1900 = 19,00 %."
                    },
                    "validFrom": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "validUntil": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "active": {
                        "type": "boolean"
                    }
                },
                "required": [
                    "id",
                    "code",
                    "name",
                    "description",
                    "unit",
                    "unitPriceCents",
                    "taxRate",
                    "validFrom",
                    "validUntil",
                    "active"
                ],
                "additionalProperties": false
            },
            "Session": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "Vollständige Sitzungskennung - sie wird zum Beenden gebraucht."
                    },
                    "ipAddress": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "device": {
                        "type": "string"
                    },
                    "lastActiveAt": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "current": {
                        "type": "boolean"
                    }
                },
                "required": [
                    "id",
                    "ipAddress",
                    "device",
                    "lastActiveAt",
                    "current"
                ],
                "additionalProperties": false
            },
            "Task": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "title": {
                        "type": "string"
                    },
                    "notes": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "open",
                            "in_progress",
                            "done",
                            "cancelled"
                        ]
                    },
                    "statusLabel": {
                        "type": "string"
                    },
                    "priority": {
                        "type": "string",
                        "enum": [
                            "low",
                            "normal",
                            "high"
                        ]
                    },
                    "priorityLabel": {
                        "type": "string"
                    },
                    "dueOn": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date"
                    },
                    "overdue": {
                        "type": "boolean",
                        "description": "Offen und die Fälligkeit liegt vor heute."
                    },
                    "recurring": {
                        "type": "boolean",
                        "description": "Vorkommen einer wiederkehrenden Aufgabe."
                    },
                    "patientId": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "ulid",
                        "description": "Öffentliche Kennung (ULID). Fortlaufende Zahlen gibt es nach außen nicht: sie verrieten die Größe des Datenbestands und luden zum Durchprobieren ein."
                    },
                    "assignees": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "id": {
                                    "type": "string",
                                    "format": "ulid",
                                    "description": "Kennung des Kontos."
                                },
                                "name": {
                                    "type": "string"
                                }
                            },
                            "required": [
                                "id",
                                "name"
                            ],
                            "additionalProperties": false
                        },
                        "description": "Leer heißt: niemand zuständig."
                    },
                    "createdBy": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "properties": {
                            "id": {
                                "type": "string",
                                "format": "ulid",
                                "description": "Kennung des Kontos."
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name"
                        ],
                        "additionalProperties": false
                    },
                    "completedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "completedBy": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "properties": {
                            "id": {
                                "type": "string",
                                "format": "ulid",
                                "description": "Kennung des Kontos."
                            },
                            "name": {
                                "type": "string"
                            }
                        },
                        "required": [
                            "id",
                            "name"
                        ],
                        "additionalProperties": false
                    },
                    "createdAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    },
                    "updatedAt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time"
                    }
                },
                "required": [
                    "id",
                    "title",
                    "notes",
                    "status",
                    "statusLabel",
                    "priority",
                    "priorityLabel",
                    "dueOn",
                    "overdue",
                    "recurring",
                    "patientId",
                    "assignees",
                    "createdBy",
                    "completedAt",
                    "completedBy",
                    "createdAt",
                    "updatedAt"
                ],
                "additionalProperties": false
            }
        }
    }
}
