{
  "openapi": "3.1.0",
  "info": {
    "title": "rentab.ly REST API",
    "version": "1.0.0",
    "description": "The rentab.ly REST API provides programmatic access to German property management data including properties, units, tenants, leases, payments, documents, tasks, and messages.\n\n## Authentication\nAll requests require a Bearer token (API key) in the Authorization header:\n```\nAuthorization: Bearer <your-api-key>\n```\n\n## Scopes\nAPI keys are scoped to specific resources. Available scopes:\n- `properties` — Access property data\n- `units` — Access unit data\n- `tenants` — Access tenant data\n- `leases` — Access lease data\n- `payments` — Access payment, operating cost, and index rent data\n- `documents` — Access document data\n- `tasks` — Access and manage tasks\n- `messages` — Create message drafts and reminders\n\n## Rate Limits\n100 requests per minute per API key. Rate limit status is returned in response headers:\n- `X-RateLimit-Limit` — Maximum requests per window\n- `X-RateLimit-Remaining` — Remaining requests in current window\n\n## Pagination\nList endpoints support `limit` (default 50, max 100) and `offset` (default 0) query parameters. Responses include `total`, `limit`, and `offset` in the response body.\n\n## Idempotency\nPOST endpoints accept an optional `idempotency_key` field to prevent duplicate operations."
  },
  "servers": [
    {
      "url": "https://rentab.ly/api/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/properties": {
      "get": {
        "operationId": "list_properties",
        "summary": "List properties",
        "description": "Returns a paginated list of properties. Requires scope: `properties`.",
        "tags": ["Properties"],
        "parameters": [
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "properties": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/Property" }
                        },
                        "total": { "type": "integer" },
                        "limit": { "type": "integer" },
                        "offset": { "type": "integer" }
                      },
                      "required": ["properties", "total", "limit", "offset"]
                    }
                  },
                  "required": ["data"]
                },
                "example": {
                  "data": {
                    "properties": [
                      {
                        "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                        "name": "Musterstraße 12",
                        "address": {
                          "street": "Musterstraße 12",
                          "city": "Berlin",
                          "zip": "10115",
                          "country": "DE"
                        },
                        "type": "apartment_building",
                        "units_count": 8,
                        "created_at": "2023-01-15T10:30:00Z",
                        "updated_at": "2024-02-20T14:00:00Z"
                      }
                    ],
                    "total": 3,
                    "limit": 50,
                    "offset": 0
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/properties/{id}": {
      "get": {
        "operationId": "get_property",
        "summary": "Get property",
        "description": "Returns a single property by ID. Requires scope: `properties`.",
        "tags": ["Properties"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Property ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "property": { "$ref": "#/components/schemas/Property" }
                      },
                      "required": ["property"]
                    }
                  },
                  "required": ["data"]
                },
                "example": {
                  "data": {
                    "property": {
                      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                      "name": "Musterstraße 12",
                      "address": {
                        "street": "Musterstraße 12",
                        "city": "Berlin",
                        "zip": "10115",
                        "country": "DE"
                      },
                      "type": "apartment_building",
                      "units_count": 8,
                      "total_area_sqm": 560.5,
                      "year_built": 1965,
                      "created_at": "2023-01-15T10:30:00Z",
                      "updated_at": "2024-02-20T14:00:00Z"
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/units": {
      "get": {
        "operationId": "list_units",
        "summary": "List units",
        "description": "Returns a paginated list of units. Optionally filter by property. Requires scope: `units`.",
        "tags": ["Units"],
        "parameters": [
          {
            "name": "property_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Filter by property ID"
          },
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "units": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/Unit" }
                        },
                        "total": { "type": "integer" },
                        "limit": { "type": "integer" },
                        "offset": { "type": "integer" }
                      },
                      "required": ["units", "total", "limit", "offset"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/units/{id}": {
      "get": {
        "operationId": "get_unit",
        "summary": "Get unit detail",
        "description": "Returns a single unit by ID. Requires scope: `units`.",
        "tags": ["Units"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Unit ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "unit": { "$ref": "#/components/schemas/Unit" }
                      },
                      "required": ["unit"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/tenants": {
      "get": {
        "operationId": "list_tenants",
        "summary": "List tenants",
        "description": "Returns a paginated list of tenants. Requires scope: `tenants`.",
        "tags": ["Tenants"],
        "parameters": [
          {
            "name": "property_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Filter by property ID"
          },
          {
            "name": "include_inactive",
            "in": "query",
            "required": false,
            "schema": { "type": "boolean", "default": false },
            "description": "Include inactive tenants"
          },
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "tenants": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/Tenant" }
                        },
                        "total": { "type": "integer" },
                        "limit": { "type": "integer" },
                        "offset": { "type": "integer" }
                      },
                      "required": ["tenants", "total", "limit", "offset"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/tenants/{id}": {
      "get": {
        "operationId": "get_tenant",
        "summary": "Get tenant detail",
        "description": "Returns a single tenant by ID. Requires scope: `tenants`.",
        "tags": ["Tenants"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Tenant ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "tenant": { "$ref": "#/components/schemas/Tenant" }
                      },
                      "required": ["tenant"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/leases": {
      "get": {
        "operationId": "list_leases",
        "summary": "List leases",
        "description": "Returns a paginated list of leases. Requires scope: `leases`.",
        "tags": ["Leases"],
        "parameters": [
          {
            "name": "property_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Filter by property ID"
          },
          {
            "name": "tenant_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Filter by tenant ID"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "enum": ["active", "terminated"] },
            "description": "Filter by lease status"
          },
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "leases": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/Lease" }
                        },
                        "total": { "type": "integer" },
                        "limit": { "type": "integer" },
                        "offset": { "type": "integer" }
                      },
                      "required": ["leases", "total", "limit", "offset"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/leases/{id}": {
      "get": {
        "operationId": "get_lease",
        "summary": "Get lease detail",
        "description": "Returns a single lease by ID. Requires scope: `leases`.",
        "tags": ["Leases"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Lease ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "lease": { "$ref": "#/components/schemas/Lease" }
                      },
                      "required": ["lease"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/payments": {
      "get": {
        "operationId": "list_payments",
        "summary": "List payments",
        "description": "Returns a paginated list of rent payments. Requires scope: `payments`.",
        "tags": ["Payments"],
        "parameters": [
          {
            "name": "tenant_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Filter by tenant ID"
          },
          {
            "name": "property_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Filter by property ID"
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "enum": ["paid", "partial", "unpaid"] },
            "description": "Filter by payment status"
          },
          {
            "name": "from_date",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "date" },
            "description": "Start date filter (inclusive)"
          },
          {
            "name": "to_date",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "date" },
            "description": "End date filter (inclusive)"
          },
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "payments": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/RentPayment" }
                        },
                        "total": { "type": "integer" },
                        "limit": { "type": "integer" },
                        "offset": { "type": "integer" }
                      },
                      "required": ["payments", "total", "limit", "offset"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/payments/open": {
      "get": {
        "operationId": "list_open_payments",
        "summary": "List open items",
        "description": "Returns unpaid or partially paid items. Requires scope: `payments`.",
        "tags": ["Payments"],
        "parameters": [
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "payments": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/RentPayment" }
                        },
                        "total": { "type": "integer" },
                        "limit": { "type": "integer" },
                        "offset": { "type": "integer" }
                      },
                      "required": ["payments", "total", "limit", "offset"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/payments/summary": {
      "get": {
        "operationId": "get_payment_summary",
        "summary": "Get rent account summary",
        "description": "Returns a summary of the rent account for a specific tenant. Requires scope: `payments`.",
        "tags": ["Payments"],
        "parameters": [
          {
            "name": "tenant_id",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Tenant ID (required)"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "tenant_id": { "type": "string", "format": "uuid" },
                        "total_owed": { "type": "number", "format": "double" },
                        "total_paid": { "type": "number", "format": "double" },
                        "balance": { "type": "number", "format": "double" },
                        "open_items_count": { "type": "integer" },
                        "total_overpaid": { "type": "number", "format": "double" },
                        "total_entries": { "type": "integer" }
                      },
                      "required": ["tenant_id", "total_owed", "total_paid", "balance", "open_items_count", "total_overpaid", "total_entries"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/payments/{id}/notes": {
      "post": {
        "operationId": "add_payment_note",
        "summary": "Add internal note to payment",
        "description": "Adds an internal note to a payment record. Requires scope: `payments`.",
        "tags": ["Payments"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Payment ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "note": { "type": "string", "description": "The note text" },
                  "idempotency_key": { "type": "string", "description": "Optional idempotency key" }
                },
                "required": ["note"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Note added successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "payment_id": { "type": "string", "format": "uuid" },
                        "note_added": { "type": "boolean" }
                      },
                      "required": ["payment_id", "note_added"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/tasks": {
      "get": {
        "operationId": "list_tasks",
        "summary": "List tasks",
        "description": "Returns a paginated list of tasks. Requires scope: `tasks`.",
        "tags": ["Tasks"],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "enum": ["open", "in_progress", "done", "cancelled"] },
            "description": "Filter by task status"
          },
          {
            "name": "property_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Filter by property ID"
          },
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "tasks": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/Task" }
                        },
                        "total": { "type": "integer" },
                        "limit": { "type": "integer" },
                        "offset": { "type": "integer" }
                      },
                      "required": ["tasks", "total", "limit", "offset"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      },
      "post": {
        "operationId": "create_task",
        "summary": "Create task",
        "description": "Creates a new task. Requires scope: `tasks`.",
        "tags": ["Tasks"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": { "type": "string", "description": "Task title" },
                  "description": { "type": "string", "description": "Task description" },
                  "priority": {
                    "type": "string",
                    "enum": ["low", "medium", "high", "urgent"],
                    "description": "Task priority"
                  },
                  "property_id": { "type": "string", "format": "uuid", "description": "Associated property ID" },
                  "unit_id": { "type": "string", "format": "uuid", "description": "Associated unit ID" },
                  "due_date": { "type": "string", "format": "date", "description": "Due date" },
                  "idempotency_key": { "type": "string", "description": "Optional idempotency key" }
                },
                "required": ["title"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Task created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "task": { "$ref": "#/components/schemas/Task" },
                        "created": { "type": "boolean" }
                      },
                      "required": ["task", "created"]
                    }
                  },
                  "required": ["data"]
                },
                "example": {
                  "data": {
                    "task": {
                      "id": "f8e7d6c5-b4a3-2190-fedc-ba0987654321",
                      "title": "Heizungswartung beauftragen",
                      "description": "Jährliche Wartung der Gasheizung",
                      "priority": "medium",
                      "status": "open",
                      "property_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
                      "unit_id": null,
                      "due_date": "2024-03-15",
                      "created_at": "2024-02-01T09:00:00Z",
                      "updated_at": "2024-02-01T09:00:00Z"
                    },
                    "created": true
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/tasks/{id}": {
      "get": {
        "operationId": "get_task",
        "summary": "Get task detail",
        "description": "Returns a single task by ID. Requires scope: `tasks`.",
        "tags": ["Tasks"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Task ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "task": { "$ref": "#/components/schemas/Task" }
                      },
                      "required": ["task"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/tasks/{id}/status": {
      "patch": {
        "operationId": "update_task_status",
        "summary": "Update task status",
        "description": "Updates the status of an existing task. Requires scope: `tasks`.",
        "tags": ["Tasks"],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Task ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": ["open", "in_progress", "done", "cancelled"]
                  }
                },
                "required": ["status"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Task status updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "task": { "$ref": "#/components/schemas/Task" },
                        "updated": { "type": "boolean" }
                      },
                      "required": ["task", "updated"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/documents": {
      "get": {
        "operationId": "list_documents",
        "summary": "List documents",
        "description": "Returns a paginated list of documents. Requires scope: `documents`.",
        "tags": ["Documents"],
        "parameters": [
          {
            "name": "property_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Filter by property ID"
          },
          {
            "name": "tenant_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Filter by tenant ID"
          },
          {
            "name": "document_type",
            "in": "query",
            "required": false,
            "schema": { "type": "string" },
            "description": "Filter by document type (e.g. lease, invoice, protocol)"
          },
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "documents": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/Document" }
                        },
                        "total": { "type": "integer" },
                        "limit": { "type": "integer" },
                        "offset": { "type": "integer" }
                      },
                      "required": ["documents", "total", "limit", "offset"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/documents/search": {
      "get": {
        "operationId": "search_documents",
        "summary": "Search documents",
        "description": "Full-text search across documents. Requires scope: `documents`.",
        "tags": ["Documents"],
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "description": "Search query string"
          },
          { "$ref": "#/components/parameters/Limit" }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "documents": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/Document" }
                        },
                        "total": { "type": "integer" },
                        "limit": { "type": "integer" }
                      },
                      "required": ["documents", "total", "limit"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/operating-costs": {
      "get": {
        "operationId": "list_operating_costs",
        "summary": "Operating cost summaries",
        "description": "Returns operating cost (Betriebskosten) summaries. Requires scope: `payments`.",
        "tags": ["Operating Costs"],
        "parameters": [
          {
            "name": "property_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Filter by property ID"
          },
          {
            "name": "year",
            "in": "query",
            "required": false,
            "schema": { "type": "integer" },
            "description": "Filter by year"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "statements": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/OperatingCostStatement" }
                        }
                      },
                      "required": ["statements"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/index-rent": {
      "get": {
        "operationId": "get_index_rent_status",
        "summary": "Index rent status",
        "description": "Returns index rent (Indexmiete) calculation status. Requires scope: `payments`.",
        "tags": ["Index Rent"],
        "parameters": [
          {
            "name": "contract_id",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "format": "uuid" },
            "description": "Filter by contract/lease ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "calculations": {
                          "type": "array",
                          "items": { "$ref": "#/components/schemas/IndexRentCalculation" }
                        }
                      },
                      "required": ["calculations"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/drafts/message": {
      "post": {
        "operationId": "prepare_tenant_message",
        "summary": "Prepare tenant message",
        "description": "Creates a draft message to a tenant that requires confirmation before sending. Requires scope: `messages`.",
        "tags": ["Drafts"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tenant_id": { "type": "string", "format": "uuid", "description": "Target tenant ID" },
                  "subject": { "type": "string", "description": "Message subject" },
                  "body": { "type": "string", "description": "Message body" },
                  "idempotency_key": { "type": "string", "description": "Optional idempotency key" }
                },
                "required": ["tenant_id", "subject", "body"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Draft created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": { "type": "string", "enum": ["draft_created"] },
                        "draft_id": { "type": "string", "format": "uuid" },
                        "requires_confirmation": { "type": "boolean" },
                        "confirmation_url": { "type": "string", "format": "uri" }
                      },
                      "required": ["status", "draft_id", "requires_confirmation", "confirmation_url"]
                    }
                  },
                  "required": ["data"]
                },
                "example": {
                  "data": {
                    "status": "draft_created",
                    "draft_id": "d1e2f3a4-b5c6-7890-1234-567890abcdef",
                    "requires_confirmation": true,
                    "confirmation_url": "https://rentab.ly/app/drafts/d1e2f3a4-b5c6-7890-1234-567890abcdef/confirm"
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/drafts/payment-reminder": {
      "post": {
        "operationId": "prepare_payment_reminder",
        "summary": "Prepare payment reminder",
        "description": "Creates a draft payment reminder for a tenant. Requires scopes: `messages`, `payments`.",
        "tags": ["Drafts"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tenant_id": { "type": "string", "format": "uuid", "description": "Target tenant ID" },
                  "payment_ids": {
                    "type": "array",
                    "items": { "type": "string", "format": "uuid" },
                    "description": "List of payment IDs to reference in the reminder"
                  },
                  "custom_message": { "type": "string", "description": "Optional custom message text" },
                  "idempotency_key": { "type": "string", "description": "Optional idempotency key" }
                },
                "required": ["tenant_id", "payment_ids"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Draft reminder created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": { "type": "string", "enum": ["draft_created"] },
                        "draft_id": { "type": "string", "format": "uuid" },
                        "requires_confirmation": { "type": "boolean" },
                        "confirmation_url": { "type": "string", "format": "uri" }
                      },
                      "required": ["status", "draft_id", "requires_confirmation", "confirmation_url"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    },
    "/drafts/index-rent-letter": {
      "post": {
        "operationId": "prepare_index_rent_letter",
        "summary": "Prepare index rent letter",
        "description": "Creates a draft index rent adjustment letter. Requires scopes: `payments`, `messages`.",
        "tags": ["Drafts"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "calculation_id": { "type": "string", "format": "uuid", "description": "Index rent calculation ID" },
                  "custom_note": { "type": "string", "description": "Optional custom note" },
                  "idempotency_key": { "type": "string", "description": "Optional idempotency key" }
                },
                "required": ["calculation_id"]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Draft letter created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "status": { "type": "string", "enum": ["draft_created"] },
                        "draft_id": { "type": "string", "format": "uuid" },
                        "requires_confirmation": { "type": "boolean" },
                        "confirmation_url": { "type": "string", "format": "uri" }
                      },
                      "required": ["status", "draft_id", "requires_confirmation", "confirmation_url"]
                    }
                  },
                  "required": ["data"]
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "422": { "$ref": "#/components/responses/ValidationError" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "500": { "$ref": "#/components/responses/InternalError" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key passed as Bearer token in the Authorization header"
      }
    },
    "parameters": {
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "default": 50,
          "minimum": 1,
          "maximum": 100
        },
        "description": "Number of items to return (max 100)"
      },
      "Offset": {
        "name": "offset",
        "in": "query",
        "required": false,
        "schema": {
          "type": "integer",
          "default": 0,
          "minimum": 0
        },
        "description": "Number of items to skip"
      }
    },
    "schemas": {
      "Property": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "name": { "type": "string" },
          "address": {
            "type": "object",
            "properties": {
              "street": { "type": "string" },
              "city": { "type": "string" },
              "zip": { "type": "string" },
              "country": { "type": "string" }
            },
            "required": ["street", "city", "zip", "country"]
          },
          "type": {
            "type": "string",
            "enum": ["apartment_building", "single_family", "commercial", "mixed_use"]
          },
          "units_count": { "type": "integer" },
          "total_area_sqm": { "type": "number", "format": "double" },
          "year_built": { "type": "integer" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        },
        "required": ["id", "name", "address", "type", "units_count", "created_at", "updated_at"]
      },
      "Unit": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "property_id": { "type": "string", "format": "uuid" },
          "name": { "type": "string", "description": "Unit identifier (e.g. 'EG links', 'Wohnung 3')" },
          "floor": { "type": "integer" },
          "area_sqm": { "type": "number", "format": "double" },
          "rooms": { "type": "number", "format": "double" },
          "type": {
            "type": "string",
            "enum": ["residential", "commercial", "parking", "storage"]
          },
          "status": {
            "type": "string",
            "enum": ["occupied", "vacant", "notice_given"]
          },
          "current_tenant_id": { "type": "string", "format": "uuid", "nullable": true },
          "base_rent": { "type": "number", "format": "double", "description": "Kaltmiete in EUR" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        },
        "required": ["id", "property_id", "name", "type", "status", "created_at", "updated_at"]
      },
      "Tenant": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "first_name": { "type": "string" },
          "last_name": { "type": "string" },
          "email": { "type": "string", "format": "email" },
          "phone": { "type": "string", "nullable": true },
          "is_active": { "type": "boolean" },
          "move_in_date": { "type": "string", "format": "date" },
          "move_out_date": { "type": "string", "format": "date", "nullable": true },
          "property_id": { "type": "string", "format": "uuid" },
          "unit_id": { "type": "string", "format": "uuid" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        },
        "required": ["id", "first_name", "last_name", "is_active", "property_id", "unit_id", "created_at", "updated_at"]
      },
      "Lease": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "tenant_id": { "type": "string", "format": "uuid" },
          "unit_id": { "type": "string", "format": "uuid" },
          "property_id": { "type": "string", "format": "uuid" },
          "status": { "type": "string", "enum": ["active", "terminated"] },
          "start_date": { "type": "string", "format": "date" },
          "end_date": { "type": "string", "format": "date", "nullable": true },
          "base_rent": { "type": "number", "format": "double", "description": "Kaltmiete in EUR" },
          "operating_costs_prepayment": { "type": "number", "format": "double", "description": "Nebenkostenvorauszahlung in EUR" },
          "total_rent": { "type": "number", "format": "double", "description": "Warmmiete in EUR" },
          "deposit_amount": { "type": "number", "format": "double", "description": "Kaution in EUR" },
          "notice_period_months": { "type": "integer" },
          "is_index_linked": { "type": "boolean", "description": "Whether this is an Indexmietvertrag" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        },
        "required": ["id", "tenant_id", "unit_id", "property_id", "status", "start_date", "base_rent", "total_rent", "created_at", "updated_at"]
      },
      "RentPayment": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "tenant_id": { "type": "string", "format": "uuid" },
          "property_id": { "type": "string", "format": "uuid" },
          "unit_id": { "type": "string", "format": "uuid" },
          "period": { "type": "string", "description": "Payment period (e.g. '2024-03')" },
          "amount_due": { "type": "number", "format": "double" },
          "amount_paid": { "type": "number", "format": "double" },
          "balance": { "type": "number", "format": "double", "description": "Negative means outstanding" },
          "status": { "type": "string", "enum": ["paid", "partial", "unpaid"] },
          "due_date": { "type": "string", "format": "date" },
          "paid_date": { "type": "string", "format": "date", "nullable": true },
          "notes": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Internal notes"
          },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        },
        "required": ["id", "tenant_id", "property_id", "unit_id", "period", "amount_due", "amount_paid", "balance", "status", "due_date", "created_at", "updated_at"]
      },
      "Task": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "title": { "type": "string" },
          "description": { "type": "string", "nullable": true },
          "priority": { "type": "string", "enum": ["low", "medium", "high", "urgent"] },
          "status": { "type": "string", "enum": ["open", "in_progress", "done", "cancelled"] },
          "property_id": { "type": "string", "format": "uuid", "nullable": true },
          "unit_id": { "type": "string", "format": "uuid", "nullable": true },
          "due_date": { "type": "string", "format": "date", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        },
        "required": ["id", "title", "priority", "status", "created_at", "updated_at"]
      },
      "Document": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "name": { "type": "string" },
          "document_type": { "type": "string", "description": "e.g. lease, invoice, protocol, notice" },
          "property_id": { "type": "string", "format": "uuid", "nullable": true },
          "tenant_id": { "type": "string", "format": "uuid", "nullable": true },
          "file_url": { "type": "string", "format": "uri" },
          "file_size_bytes": { "type": "integer" },
          "mime_type": { "type": "string" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        },
        "required": ["id", "name", "document_type", "file_url", "mime_type", "created_at", "updated_at"]
      },
      "OperatingCostStatement": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "property_id": { "type": "string", "format": "uuid" },
          "year": { "type": "integer" },
          "status": { "type": "string", "enum": ["draft", "finalized", "sent"] },
          "total_costs": { "type": "number", "format": "double" },
          "total_prepayments": { "type": "number", "format": "double" },
          "balance": { "type": "number", "format": "double", "description": "Positive means tenant owes, negative means refund" },
          "due_date": { "type": "string", "format": "date", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        },
        "required": ["id", "property_id", "year", "status", "total_costs", "total_prepayments", "balance", "created_at", "updated_at"]
      },
      "IndexRentCalculation": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "lease_id": { "type": "string", "format": "uuid" },
          "tenant_id": { "type": "string", "format": "uuid" },
          "base_index": { "type": "number", "format": "double", "description": "CPI value at lease start" },
          "current_index": { "type": "number", "format": "double", "description": "Current CPI value" },
          "percentage_change": { "type": "number", "format": "double" },
          "current_rent": { "type": "number", "format": "double" },
          "proposed_rent": { "type": "number", "format": "double" },
          "effective_date": { "type": "string", "format": "date" },
          "status": { "type": "string", "enum": ["pending", "notified", "applied", "rejected"] },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        },
        "required": ["id", "lease_id", "tenant_id", "base_index", "current_index", "percentage_change", "current_rent", "proposed_rent", "effective_date", "status", "created_at", "updated_at"]
      },
      "Draft": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "type": { "type": "string", "enum": ["message", "payment_reminder", "index_rent_letter"] },
          "status": { "type": "string", "enum": ["draft_created", "confirmed", "sent", "cancelled"] },
          "tenant_id": { "type": "string", "format": "uuid" },
          "requires_confirmation": { "type": "boolean" },
          "confirmation_url": { "type": "string", "format": "uri" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        },
        "required": ["id", "type", "status", "tenant_id", "requires_confirmation", "created_at", "updated_at"]
      },
      "PaginationMeta": {
        "type": "object",
        "properties": {
          "total": { "type": "integer", "description": "Total number of matching items" },
          "limit": { "type": "integer", "description": "Items per page" },
          "offset": { "type": "integer", "description": "Current offset" }
        },
        "required": ["total", "limit", "offset"]
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": ["bad_request", "unauthorized", "forbidden", "not_found", "validation_error", "rate_limited", "internal_error"]
              },
              "message": { "type": "string" }
            },
            "required": ["code", "message"]
          }
        },
        "required": ["error"]
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Bad request",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" },
            "example": {
              "error": {
                "code": "bad_request",
                "message": "Invalid query parameter: limit must be between 1 and 100"
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Unauthorized — missing or invalid API key",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" },
            "example": {
              "error": {
                "code": "unauthorized",
                "message": "Invalid or missing API key"
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "Forbidden — API key lacks required scope",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" },
            "example": {
              "error": {
                "code": "forbidden",
                "message": "API key does not have the required scope: payments"
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" },
            "example": {
              "error": {
                "code": "not_found",
                "message": "Property with ID a1b2c3d4-e5f6-7890-abcd-ef1234567890 not found"
              }
            }
          }
        }
      },
      "ValidationError": {
        "description": "Validation error — request body is invalid",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" },
            "example": {
              "error": {
                "code": "validation_error",
                "message": "Field 'title' is required"
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" },
            "example": {
              "error": {
                "code": "rate_limited",
                "message": "Rate limit exceeded. Please retry after 60 seconds."
              }
            }
          }
        },
        "headers": {
          "X-RateLimit-Limit": {
            "schema": { "type": "integer" },
            "description": "Maximum requests per window"
          },
          "X-RateLimit-Remaining": {
            "schema": { "type": "integer" },
            "description": "Remaining requests in current window"
          }
        }
      },
      "InternalError": {
        "description": "Internal server error",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/ErrorResponse" },
            "example": {
              "error": {
                "code": "internal_error",
                "message": "An unexpected error occurred. Please try again later."
              }
            }
          }
        }
      }
    }
  },
  "tags": [
    { "name": "Properties", "description": "Manage properties (Immobilien)" },
    { "name": "Units", "description": "Manage units (Einheiten)" },
    { "name": "Tenants", "description": "Manage tenants (Mieter)" },
    { "name": "Leases", "description": "Manage leases (Mietverträge)" },
    { "name": "Payments", "description": "Manage rent payments (Mietzahlungen)" },
    { "name": "Tasks", "description": "Manage tasks (Aufgaben)" },
    { "name": "Documents", "description": "Manage documents (Dokumente)" },
    { "name": "Operating Costs", "description": "Operating cost statements (Betriebskostenabrechnungen)" },
    { "name": "Index Rent", "description": "Index rent calculations (Indexmiete)" },
    { "name": "Drafts", "description": "Draft messages and letters (Entwürfe)" }
  ]
}
