{"openapi": "3.1.0", "info": {"title": "anhome-backend", "description": "Error responses carry a stable machine-readable `error.code` (the client-translation contract) plus a human-readable `error.message` localized to the request `Accept-Language` (supported locales: `vi`, `en`; default `vi`). The negotiated locale is echoed in the `Content-Language` response header. `error.code` and validation `error.fields[].path`/`error.fields[].code` are identical across locales \u2014 translate against those, not the message text. See ADR 0011.", "license": {"name": ""}, "version": "0.1.0"}, "servers": [{"url": "https://api.anhome.gtmlabs.vn"}], "paths": {"/api/v1/openapi.json": {"get": {"tags": ["Health"], "summary": "OpenAPI schema", "description": "Returns the generated OpenAPI 3.1 document used by Mintlify, SDK generators, and integration tooling.", "operationId": "openapi_json_doc", "responses": {"200": {"description": "OpenAPI 3.1 document", "content": {"application/json": {"schema": {}}}}}, "security": []}}, "/api/v1/health": {"get": {"tags": ["Health"], "summary": "Health check", "description": "Checks whether the HTTP process is running. This endpoint does not require authentication and does not check database connectivity.", "operationId": "health", "responses": {"200": {"description": "Service is running", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/HealthResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}}, "security": []}}, "/api/v1/ready": {"get": {"tags": ["Health"], "summary": "Readiness check", "description": "Checks whether the service can reach its required runtime dependencies, including the PostgreSQL database.", "operationId": "ready", "responses": {"200": {"description": "Database connectivity is ready", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/HealthResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "500": {"description": "Readiness check failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/auth/register": {"post": {"tags": ["Authentication"], "summary": "Register account", "description": "Creates the first user account for a landlord workspace, bootstraps the organization, and returns access and refresh tokens.", "operationId": "register", "requestBody": {"description": "Username, email, password, and initial organization details for account bootstrap.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RegisterRequest"}, "example": {"display_name": "Demo Owner", "email": "owner@example.com", "organization_name": "Demo Boarding House", "password": "change-me-123", "username": "demo_owner"}}}, "required": true}, "responses": {"200": {"description": "Registered user and bootstrap organization", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/AuthResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid registration payload", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Username, email, or organization already exists", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/auth/login": {"post": {"tags": ["Authentication"], "summary": "Log in", "description": "Authenticates a user by username or email and returns a new access token plus refresh token pair. Credential failures return HTTP 401 with error.code `invalid_credentials` so clients can show login-specific copy without confusing it with missing bearer-token authentication.", "operationId": "login", "requestBody": {"description": "Username or email plus password credentials for session creation.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LoginRequest"}, "example": {"password": "change-me-123", "username_or_email": "demo_owner"}}}, "required": true}, "responses": {"200": {"description": "Authenticated session tokens", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/AuthResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid login payload", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Invalid credentials; response error.code is invalid_credentials", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/auth/oauth/providers": {"get": {"tags": ["Authentication"], "summary": "Oauth providers", "description": "Documents an AnHome API operation.", "operationId": "oauth_providers", "responses": {"200": {"description": "Enabled OAuth providers for the admin web login screen", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OAuthProvidersResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/auth/oauth/{provider}/start": {"get": {"tags": ["Authentication"], "summary": "Oauth start", "description": "Documents an AnHome API operation.", "operationId": "oauth_start", "parameters": [{"name": "provider", "in": "path", "description": "OAuth provider", "required": true, "schema": {"$ref": "#/components/schemas/SocialProvider"}}, {"name": "redirect_to", "in": "query", "description": "Sanitized admin-web relative path to return to after login", "required": false, "schema": {"type": "string"}}], "responses": {"302": {"description": "Redirects the browser to the provider authorization endpoint"}, "400": {"description": "Provider is not configured or the request is invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/auth/oauth/{provider}/callback": {"get": {"tags": ["Authentication"], "summary": "Oauth callback get", "description": "Documents an AnHome API operation.", "operationId": "oauth_callback_get", "parameters": [{"name": "provider", "in": "path", "description": "OAuth provider", "required": true, "schema": {"$ref": "#/components/schemas/SocialProvider"}}, {"name": "code", "in": "query", "description": "Authorization code returned by the provider", "required": false, "schema": {"type": "string"}}, {"name": "state", "in": "query", "description": "One-time state value created by the start endpoint", "required": false, "schema": {"type": "string"}}, {"name": "error", "in": "query", "description": "Provider error code if authorization failed", "required": false, "schema": {"type": "string"}}], "responses": {"303": {"description": "Redirects the browser to the admin web callback with a short-lived handoff code"}, "400": {"description": "OAuth provider exchange failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}, "post": {"tags": ["Authentication"], "summary": "Oauth callback post", "description": "Documents an AnHome API operation.", "operationId": "oauth_callback_post", "parameters": [{"name": "provider", "in": "path", "description": "OAuth provider", "required": true, "schema": {"$ref": "#/components/schemas/SocialProvider"}}], "requestBody": {"description": "JSON payload used to oauth callback post.", "content": {"application/x-www-form-urlencoded": {"schema": {}, "example": {"code": "provider-authorization-code", "state": "stored-state"}}}, "required": true}, "responses": {"303": {"description": "Redirects the browser to the admin web callback with a short-lived handoff code"}, "400": {"description": "OAuth provider exchange failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/auth/oauth/exchange": {"post": {"tags": ["Authentication"], "summary": "Oauth exchange", "description": "Documents an AnHome API operation.", "operationId": "oauth_exchange", "requestBody": {"description": "JSON payload used to oauth exchange.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OAuthExchangeRequest"}, "example": {"handoff_code": "short-lived-handoff-code"}}}, "required": true}, "responses": {"200": {"description": "OAuth handoff exchanged for an AnHome session or pending signup token", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OAuthExchangeResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Handoff code is invalid or expired", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/auth/oauth/complete-signup": {"post": {"tags": ["Authentication"], "summary": "Complete oauth signup", "description": "Documents an AnHome API operation.", "operationId": "complete_oauth_signup", "requestBody": {"description": "JSON payload used to complete oauth signup.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CompleteOAuthSignupRequest"}, "example": {"display_name": "Demo Owner", "organization_name": "Demo Boarding House", "signup_token": "short-lived-signup-token", "username": "demo_owner"}}}, "required": true}, "responses": {"200": {"description": "Created social user, organization, owner membership, and AnHome session", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/AuthResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Signup token or request body is invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Username, email, or organization already exists", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/auth/refresh": {"post": {"tags": ["Authentication"], "summary": "Refresh session", "description": "Exchanges a valid stored refresh token for a fresh access token and refresh token pair.", "operationId": "refresh", "requestBody": {"description": "Stored refresh token to rotate into a fresh token pair.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RefreshRequest"}, "example": {"refresh_token": "paste-refresh-token-here"}}}, "required": true}, "responses": {"200": {"description": "Refreshed access and refresh tokens", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RefreshResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid refresh payload", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Refresh token is invalid or revoked", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/auth/logout": {"post": {"tags": ["Authentication"], "summary": "Log out", "description": "Revokes the submitted refresh token so it can no longer be used to create new sessions.", "operationId": "logout", "requestBody": {"description": "Refresh token that should be revoked for logout.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/LogoutRequest"}, "example": {"refresh_token": "paste-refresh-token-here"}}}, "required": true}, "responses": {"200": {"description": "Refresh token was revoked", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/LogoutResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Access token is missing or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/me": {"get": {"tags": ["Authentication"], "summary": "Get current user", "description": "Returns the authenticated user, memberships, and currently resolved organization context.", "operationId": "me", "responses": {"200": {"description": "Current user and active organization", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MeResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Access token is missing or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Authentication"], "summary": "Update current user", "description": "Updates the authenticated user's editable profile fields (display name and email) and returns the refreshed user and organization context.", "operationId": "update_me", "requestBody": {"description": "JSON payload used to update current user.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateMeRequest"}, "example": {"display_name": "Nguy\u1ec5n V\u0103n A", "email": "new-email@example.com"}}}, "required": true}, "responses": {"200": {"description": "Updated user and active organization", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MeResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid profile payload", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Access token is missing or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Email already in use", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/me/password": {"post": {"tags": ["Authentication"], "summary": "Change current user password", "description": "Changes the authenticated owner user's local password after verifying the current password. Social-only accounts without a local password return a stable business error.", "operationId": "change_password", "requestBody": {"description": "JSON payload used to change current user password.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChangePasswordRequest"}, "example": {"current_password": "current-password", "new_password": "new-secure-password-123", "refresh_token": "optional-current-refresh-token"}}}, "required": true}, "responses": {"200": {"description": "Password changed and refresh sessions hardened", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/CommandAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid password-change payload", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Access token is missing or invalid, or the current password is wrong", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Account has no local password because it was created through social login", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/me/notification-preferences": {"get": {"tags": ["Authentication"], "summary": "Owner notification preferences", "description": "Documents an AnHome API operation.", "operationId": "owner_notification_preferences", "responses": {"200": {"description": "Owner notification preferences, created with defaults when missing", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OwnerNotificationPreferencesResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Access token is missing or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Authentication"], "summary": "Update owner notification preferences", "description": "Documents an AnHome API operation.", "operationId": "update_owner_notification_preferences", "requestBody": {"description": "JSON payload used to update owner notification preferences.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OwnerUpdateNotificationPreferencesRequest"}, "example": {"email_enabled": true, "invoice_updates": true, "maintenance_updates": false, "message_updates": true, "push_enabled": false}}}, "required": true}, "responses": {"200": {"description": "Updated owner notification preferences; omitted fields keep their previous value", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OwnerNotificationPreferencesResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid preference payload", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Access token is missing or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/devices": {"post": {"tags": ["Authentication"], "summary": "Register push device", "description": "Documents an AnHome API operation.", "operationId": "register_push_device", "requestBody": {"description": "JSON payload used to register push device.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RegisterPushDeviceRequest"}, "example": {"app_instance_id": "firebase-installation-id", "device_token": "fcm-registration-token", "label": "Justin's iPhone", "platform": "ios"}}}, "required": true}, "responses": {"200": {"description": "Registered or refreshed a push device for the authenticated landlord or tenant principal", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PushDeviceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid device payload or unsupported platform", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Access token is missing or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/devices/{device_id}": {"delete": {"tags": ["Authentication"], "summary": "Delete push device", "description": "Documents an AnHome API operation.", "operationId": "delete_push_device", "parameters": [{"name": "device_id", "in": "path", "description": "Push device ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Device binding revoked for the authenticated principal", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/CommandAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Access token is missing or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Device is unknown or does not belong to the authenticated principal", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/devices/unregister": {"post": {"tags": ["Authentication"], "summary": "Unregister push device", "description": "Documents an AnHome API operation.", "operationId": "unregister_push_device", "requestBody": {"description": "JSON payload used to unregister push device.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UnregisterPushDeviceRequest"}, "example": {"device_token": "fcm-registration-token"}}}, "required": true}, "responses": {"200": {"description": "Best-effort revocation for the authenticated principal and token", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/CommandAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid device payload", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Access token is missing or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/me/devices": {"post": {"tags": ["Authentication"], "summary": "Register owner device", "description": "Documents an AnHome API operation.", "operationId": "register_owner_device", "requestBody": {"description": "JSON payload used to register owner device.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OwnerRegisterDeviceRequest"}, "example": {"device_token": "expo-push-token-or-apns-token", "label": "Justin's iPhone", "platform": "ios"}}}, "required": true}, "responses": {"200": {"description": "Registered or refreshed an owner device by user and device token", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OwnerDeviceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid device payload or unsupported platform", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Access token is missing or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/me/devices/{device_id}": {"delete": {"tags": ["Authentication"], "summary": "Delete owner device", "description": "Documents an AnHome API operation.", "operationId": "delete_owner_device", "parameters": [{"name": "device_id", "in": "path", "description": "Owner device ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Delete acknowledgement for an owner-scoped device", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/CommandAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Access token is missing or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Device is unknown or does not belong to the authenticated owner", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/organizations": {"get": {"tags": ["Organizations"], "summary": "List organizations", "description": "Lists organizations visible to the authenticated user based on active memberships.", "operationId": "list_organizations", "responses": {"200": {"description": "Organizations visible to the authenticated user", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OrganizationListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Organizations"], "summary": "Create organization", "description": "Creates an additional landlord organization for the authenticated user and grants owner membership.", "operationId": "create_organization", "requestBody": {"description": "JSON payload used to create organization.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateOrganizationRequest"}}}, "required": true}, "responses": {"200": {"description": "Created organization", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OrganizationDetailResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/organizations/current": {"get": {"tags": ["Organizations"], "summary": "Current organization", "description": "Returns the organization context selected for the current request, including role and plan metadata.", "operationId": "current_organization", "responses": {"200": {"description": "Active organization context", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/CurrentOrganizationResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/organizations/{organization_id}": {"get": {"tags": ["Organizations"], "summary": "Get organization", "description": "Returns an organization visible to the caller. Cross-organization access is rejected by the membership guard.", "operationId": "organization_detail", "parameters": [{"name": "organization_id", "in": "path", "description": "Organization ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Organization detail", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OrganizationDetailResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Organization is not visible", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Organizations"], "summary": "Update organization", "description": "Updates editable organization profile fields for a workspace the caller is allowed to manage.", "operationId": "update_organization", "parameters": [{"name": "organization_id", "in": "path", "description": "Organization ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to update organization.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateOrganizationRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated organization", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OrganizationDetailResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/organizations/{organization_id}/members": {"get": {"tags": ["Organizations"], "summary": "List organization members", "description": "Lists active and invited members for an organization, including their organization roles.", "operationId": "list_organization_members", "parameters": [{"name": "organization_id", "in": "path", "description": "Organization ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Organization members", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OrganizationMembersResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Organizations"], "summary": "Add organization member", "description": "Adds a user to an organization with the requested role, or prepares a membership for an existing account.", "operationId": "add_organization_member", "parameters": [{"name": "organization_id", "in": "path", "description": "Organization ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to add organization member.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddMemberRequest"}}}, "required": true}, "responses": {"200": {"description": "Added organization member", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OrganizationMemberResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/organizations/{organization_id}/members/{membership_id}": {"delete": {"tags": ["Organizations"], "summary": "Remove organization member", "description": "Removes a member from an organization without deleting the underlying user account.", "operationId": "remove_organization_member", "parameters": [{"name": "organization_id", "in": "path", "description": "Organization ID", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "membership_id", "in": "path", "description": "Membership ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Removed organization member", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OrganizationMemberResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Organizations"], "summary": "Update organization member", "description": "Changes a member role or membership status within the organization membership boundary.", "operationId": "update_organization_member", "parameters": [{"name": "organization_id", "in": "path", "description": "Organization ID", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "membership_id", "in": "path", "description": "Membership ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to update organization member.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateMemberRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated organization member", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OrganizationMemberResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/properties": {"get": {"tags": ["Properties"], "summary": "List properties", "description": "Lists non-archived properties belonging to the resolved organization.", "operationId": "list_properties", "responses": {"200": {"description": "Organization properties", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PropertyListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Properties"], "summary": "Create property", "description": "Creates a property record under the resolved organization for room, renter, lease, and billing operations.", "operationId": "create_property", "requestBody": {"description": "JSON payload used to create property.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreatePropertyRequest"}}}, "required": true}, "responses": {"200": {"description": "Created property", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PropertyResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/properties/{property_id}": {"get": {"tags": ["Properties"], "summary": "Get property", "description": "Returns one organization-scoped property by id, including its current persisted profile fields.", "operationId": "property_detail", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Property detail", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PropertyResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "delete": {"tags": ["Properties"], "summary": "Archive property", "description": "Archives a property so it no longer appears in active property workflows.", "operationId": "archive_property", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Archived property", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PropertyResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Properties"], "summary": "Update property", "description": "Updates editable property profile fields while keeping the property scoped to its organization.", "operationId": "update_property", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to update property.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdatePropertyRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated property", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PropertyResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/properties/{property_id}/rooms": {"get": {"tags": ["Properties"], "summary": "List property rooms", "description": "Lists rooms that belong to a property in the current organization, with optional status, search, archived, period, and pagination filters. When period is supplied, each room includes the canonical meter-reading completeness for that billing month.", "operationId": "list_property_rooms", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "status", "in": "query", "description": "Filter by room status", "required": false, "schema": {"$ref": "#/components/schemas/RoomStatus"}}, {"name": "search", "in": "query", "description": "Case-insensitive match on room name or floor", "required": false, "schema": {"type": "string", "maxLength": 120}}, {"name": "include_archived", "in": "query", "description": "Include archived rooms (default false)", "required": false, "schema": {"type": "boolean"}}, {"name": "period", "in": "query", "description": "Optional billing period in YYYY-MM. When supplied, each room includes meter_reading_status and meter_reading_id for that period.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "limit", "in": "query", "description": "Page size 1-500 (default 100)", "required": false, "schema": {"type": "integer", "format": "int64", "maximum": 500, "minimum": 1}}, {"name": "offset", "in": "query", "description": "Page offset (default 0)", "required": false, "schema": {"type": "integer", "format": "int64", "minimum": 0}}], "responses": {"200": {"description": "Rooms in property", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RoomListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Properties"], "summary": "Create property room", "description": "Creates a room inside a property and initializes its operational status for leasing workflows.", "operationId": "create_property_room", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to create property room.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateRoomRequest"}}}, "required": true}, "responses": {"200": {"description": "Created room", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RoomResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/rooms": {"get": {"tags": ["Properties"], "summary": "List rooms", "description": "Lists rooms across the current organization with optional property, status, search, archived, period, and pagination filters. When period is supplied, each room includes the canonical meter-reading completeness for that billing month.", "operationId": "list_rooms", "parameters": [{"name": "property_id", "in": "query", "description": "Filter by property; all properties in the organization when omitted", "required": false, "schema": {"type": "string", "format": "uuid"}}, {"name": "status", "in": "query", "description": "Filter by room status", "required": false, "schema": {"$ref": "#/components/schemas/RoomStatus"}}, {"name": "search", "in": "query", "description": "Case-insensitive match on room name or floor", "required": false, "schema": {"type": "string", "maxLength": 120}}, {"name": "include_archived", "in": "query", "description": "Include archived rooms (default false)", "required": false, "schema": {"type": "boolean"}}, {"name": "period", "in": "query", "description": "Optional billing period in YYYY-MM. When supplied, each room includes meter_reading_status and meter_reading_id for that period.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "limit", "in": "query", "description": "Page size 1-500 (default 100)", "required": false, "schema": {"type": "integer", "format": "int64", "maximum": 500, "minimum": 1}}, {"name": "offset", "in": "query", "description": "Page offset (default 0)", "required": false, "schema": {"type": "integer", "format": "int64", "minimum": 0}}], "responses": {"200": {"description": "Organization rooms", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RoomListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/properties/{property_id}/rooms/bulk-create": {"post": {"tags": ["Properties"], "summary": "Bulk create property rooms", "description": "Creates multiple rooms inside one property for owner onboarding. The operation validates the generated room names before insertion and commits all rooms atomically; if any generated name conflicts, no rooms are created.", "operationId": "bulk_create_property_rooms", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to bulk create property rooms.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkCreateRoomsRequest"}}}, "required": true}, "responses": {"200": {"description": "Created rooms atomically for owner onboarding", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/BulkCreateRoomsResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid generated room batch, including invalid count, start_number, name_prefix, or generated room name length (code invalid_room_bulk_create)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Access token is missing or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Authenticated user lacks ManageRoom permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Property is missing or not visible in the current organization", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "At least one generated room name already exists in this property; no rooms are created (code room_name_already_exists)", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/rooms/{room_id}": {"get": {"tags": ["Properties"], "summary": "Get room", "description": "Returns a room by id when it belongs to the caller's current organization.", "operationId": "room_detail", "parameters": [{"name": "room_id", "in": "path", "description": "Room ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Room detail", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RoomResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "delete": {"tags": ["Properties"], "summary": "Archive room", "description": "Archives a room and removes it from active room lists without deleting historical records.", "operationId": "archive_room", "parameters": [{"name": "room_id", "in": "path", "description": "Room ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Archived room", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RoomResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Properties"], "summary": "Update room", "description": "Updates editable room attributes such as name, floor, area, and base rent. The status field sets only the operational override (ADR 0017): VACANT clears it to AVAILABLE, HIDDEN/MAINTENANCE set it, and OCCUPIED is rejected (422) because occupancy is derived from the active lease. The response status is derived and has_active_lease carries the true occupancy.", "operationId": "update_room", "parameters": [{"name": "room_id", "in": "path", "description": "Room ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to update room.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateRoomRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated room", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RoomResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "422": {"description": "status=OCCUPIED is not settable; occupancy is derived from the active lease (code room_occupancy_not_settable). ADR 0017.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/rooms/{room_id}/status": {"patch": {"tags": ["Properties"], "summary": "Update room status", "description": "Sets the room operational status (AVAILABLE/HIDDEN/MAINTENANCE) and records the transition in room history (ADR 0017). VACANT maps to AVAILABLE; OCCUPIED is rejected (422 room_occupancy_not_settable) since occupancy is derived from the active lease.", "operationId": "update_room_status", "parameters": [{"name": "room_id", "in": "path", "description": "Room ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to update room status.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateRoomStatusRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated room status", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RoomResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "422": {"description": "status=OCCUPIED is not settable; occupancy is derived from the active lease (code room_occupancy_not_settable). ADR 0017.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/rooms/{room_id}/history": {"get": {"tags": ["Properties"], "summary": "Room status history", "description": "Lists historical room status transitions for audit and diagnostics.", "operationId": "room_status_history", "parameters": [{"name": "room_id", "in": "path", "description": "Room ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Room status history", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RoomStatusHistoryListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/renters": {"get": {"tags": ["Properties"], "summary": "List renters", "description": "Lists renter profiles in the resolved organization, with optional search/phone/email/identity filters and pagination so a client can pre-check for an existing renter before creating one.", "operationId": "list_renters", "parameters": [{"name": "search", "in": "query", "description": "Case-insensitive substring match on name, phone, email, or identity number", "required": false, "schema": {"type": "string", "maxLength": 160}}, {"name": "phone", "in": "query", "description": "Exact phone match", "required": false, "schema": {"type": "string", "maxLength": 40}}, {"name": "email", "in": "query", "description": "Case-insensitive exact email match", "required": false, "schema": {"type": "string", "maxLength": 160}}, {"name": "identity_number", "in": "query", "description": "Exact identity number match", "required": false, "schema": {"type": "string", "maxLength": 80}}, {"name": "include_archived", "in": "query", "description": "Include archived renters (default false)", "required": false, "schema": {"type": "boolean"}}, {"name": "limit", "in": "query", "description": "Page size 1-500 (default 100)", "required": false, "schema": {"type": "integer", "format": "int64", "maximum": 500, "minimum": 1}}, {"name": "offset", "in": "query", "description": "Page offset (default 0)", "required": false, "schema": {"type": "integer", "format": "int64", "minimum": 0}}], "responses": {"200": {"description": "Renters", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RenterListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Properties"], "summary": "Create renter", "description": "Creates a renter profile that can later be attached to room leases and invoices. Duplicate-aware within the organization (ADR 0016): a strong identity_number/email match returns 409 duplicate_renter, and weaker phone/name matches return 409 duplicate_renter_candidates with candidates in error.details.", "operationId": "create_renter", "requestBody": {"description": "JSON payload used to create renter.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateRenterRequest"}}}, "required": true}, "responses": {"200": {"description": "Created renter", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RenterResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Duplicate renter (ADR 0016): a strong identity match returns code `duplicate_renter` with `error.details.renter`; weaker matches return code `duplicate_renter_candidates` with `error.details.candidates`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/renters/{renter_id}": {"get": {"tags": ["Properties"], "summary": "Get renter", "description": "Returns one renter profile when it belongs to the caller's current organization.", "operationId": "renter_detail", "parameters": [{"name": "renter_id", "in": "path", "description": "Renter ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Renter detail", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RenterResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "delete": {"tags": ["Properties"], "summary": "Archive renter", "description": "Archives a renter profile while preserving lease, invoice, payment, and audit history.", "operationId": "archive_renter", "parameters": [{"name": "renter_id", "in": "path", "description": "Renter ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Archived renter", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RenterResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Properties"], "summary": "Update renter", "description": "Updates editable renter identity and contact fields.", "operationId": "update_renter", "parameters": [{"name": "renter_id", "in": "path", "description": "Renter ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to update renter.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateRenterRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated renter", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RenterResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/leases": {"post": {"tags": ["Properties"], "summary": "Start lease", "description": "Starts a lease for a room and renter, enforcing organization scope and one active lease per room.", "operationId": "start_lease", "requestBody": {"description": "Lease lifecycle fields such as room, renter, rent, deposit, occupant count, dates, and reason.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/StartLeaseRequest"}}}, "required": true}, "responses": {"200": {"description": "Started lease", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/LeaseResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/rooms/{room_id}/leases": {"post": {"tags": ["Properties"], "summary": "Start room lease", "description": "Starts a lease for the room in the path, using the request body for renter and lease terms.", "operationId": "start_room_lease", "parameters": [{"name": "room_id", "in": "path", "description": "Room ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Lease lifecycle fields such as room, renter, rent, deposit, occupant count, dates, and reason.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/StartLeaseForRoomRequest"}}}, "required": true}, "responses": {"200": {"description": "Started lease for room", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/LeaseResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/rooms/{room_id}/leases/current": {"get": {"tags": ["Properties"], "summary": "Current room lease", "description": "Returns the active lease for a room when one exists and is visible to the current organization.", "operationId": "current_room_lease", "parameters": [{"name": "room_id", "in": "path", "description": "Room ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Current room lease", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/LeaseResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/leases/{lease_id}": {"patch": {"tags": ["Properties"], "summary": "Update lease", "description": "Updates lease terms such as rent, deposit, occupants, and end date within allowed lifecycle states.", "operationId": "update_lease", "parameters": [{"name": "lease_id", "in": "path", "description": "Lease ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Lease lifecycle fields such as room, renter, rent, deposit, occupant count, dates, and reason.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateLeaseRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated lease", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/LeaseResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/leases/{lease_id}/end": {"post": {"tags": ["Properties"], "summary": "End lease", "description": "Ends an active lease and coordinates the room state back toward vacancy.", "operationId": "end_lease", "parameters": [{"name": "lease_id", "in": "path", "description": "Lease ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Lease lifecycle fields such as room, renter, rent, deposit, occupant count, dates, and reason.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/EndLeaseRequest"}}}, "required": true}, "responses": {"200": {"description": "Ended lease", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/LeaseResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/leases/{lease_id}/cancel": {"post": {"tags": ["Properties"], "summary": "Cancel lease", "description": "Cancels a lease that should no longer be treated as active while preserving an audit trail.", "operationId": "cancel_lease", "parameters": [{"name": "lease_id", "in": "path", "description": "Lease ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Lease lifecycle fields such as room, renter, rent, deposit, occupant count, dates, and reason.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CancelLeaseRequest"}}}, "required": true}, "responses": {"200": {"description": "Cancelled lease", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/LeaseResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/renters/{renter_id}/leases": {"get": {"tags": ["Properties"], "summary": "List renter leases", "description": "Lists lease history for a renter in the current organization.", "operationId": "list_renter_leases", "parameters": [{"name": "renter_id", "in": "path", "description": "Renter ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Leases for renter", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/LeaseListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/billing-settings/{property_id}": {"get": {"tags": ["Billing"], "summary": "Get billing settings", "description": "Returns billing settings for a property, including due day and utility pricing configuration.", "operationId": "get_billing_settings", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Billing settings", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/BillingSettingsResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "put": {"tags": ["Billing"], "summary": "Upsert billing settings", "description": "Creates or replaces billing settings for a property in one idempotent request.", "operationId": "upsert_billing_settings", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to upsert billing settings.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpsertBillingSettingsRequest"}}}, "required": true}, "responses": {"200": {"description": "Upserted billing settings", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/BillingSettingsResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/properties/{property_id}/billing-settings": {"get": {"tags": ["Billing"], "summary": "Get property billing settings", "description": "Alias for reading billing settings through the property-scoped route family.", "operationId": "get_property_billing_settings", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Billing settings", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/BillingSettingsResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "put": {"tags": ["Billing"], "summary": "Upsert property billing settings", "description": "Alias for creating or replacing billing settings through the property-scoped route family.", "operationId": "upsert_property_billing_settings", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to upsert property billing settings.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpsertBillingSettingsRequest"}}}, "required": true}, "responses": {"200": {"description": "Upserted billing settings", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/BillingSettingsResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/properties/{property_id}/fee-templates": {"get": {"tags": ["Billing"], "summary": "List property fee templates", "description": "Lists recurring fee templates configured for a property.", "operationId": "list_property_fee_templates", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Fee templates for property", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/FeeTemplateListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Billing"], "summary": "Create property fee template", "description": "Creates a recurring fee template that invoice generation can apply to rooms in the property.", "operationId": "create_property_fee_template", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to create property fee template.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateFeeTemplateRequest"}}}, "required": true}, "responses": {"200": {"description": "Created fee template", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/FeeTemplateResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/fee-templates/{fee_template_id}": {"get": {"tags": ["Billing"], "summary": "Get fee template", "description": "Returns one fee template when it belongs to the caller's current organization.", "operationId": "fee_template_detail", "parameters": [{"name": "fee_template_id", "in": "path", "description": "Fee template ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Fee template detail", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/FeeTemplateResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "delete": {"tags": ["Billing"], "summary": "Delete fee template", "description": "Deletes a fee template so it will not be used for future invoice generation.", "operationId": "delete_fee_template", "parameters": [{"name": "fee_template_id", "in": "path", "description": "Fee template ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Deleted fee template", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/FeeTemplateResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Billing"], "summary": "Update fee template", "description": "Updates a recurring fee template used by future invoice generation.", "operationId": "update_fee_template", "parameters": [{"name": "fee_template_id", "in": "path", "description": "Fee template ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to update fee template.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateFeeTemplateRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated fee template", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/FeeTemplateResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/properties/{property_id}/meter-readings": {"get": {"tags": ["Billing"], "summary": "List property meter readings", "description": "Lists meter readings for rooms in a property for the requested billing period.", "operationId": "list_property_meter_readings", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "period", "in": "query", "description": "Billing period in YYYY-MM", "required": true, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}], "responses": {"200": {"description": "Meter readings for property and period", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MeterReadingListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Billing"], "summary": "Bulk upsert property meter readings", "description": "Creates or updates meter readings for multiple rooms in a property and validates period and non-decreasing usage.", "operationId": "bulk_upsert_property_meter_readings", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Meter period and usage values. The API validates YYYY-MM periods and non-decreasing readings.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkUpsertMeterReadingsRequest"}}}, "required": true}, "responses": {"200": {"description": "Bulk upserted meter readings", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/BulkUpsertMeterReadingsResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/properties/{property_id}/meter-readings/bulk-upsert": {"post": {"tags": ["Billing"], "summary": "Bulk upsert property meter readings", "description": "Compatibility alias for bulk meter reading upserts using the explicit bulk-upsert route.", "operationId": "bulk_upsert_property_meter_readings_alias", "parameters": [{"name": "property_id", "in": "path", "description": "Property ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Meter period and usage values. The API validates YYYY-MM periods and non-decreasing readings.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/BulkUpsertMeterReadingsRequest"}}}, "required": true}, "responses": {"200": {"description": "Bulk upserted meter readings", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/BulkUpsertMeterReadingsResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/rooms/{room_id}/meter-readings": {"get": {"tags": ["Billing"], "summary": "List room meter readings", "description": "Lists meter reading history for a room, optionally filtered by billing period.", "operationId": "list_room_meter_readings", "parameters": [{"name": "room_id", "in": "path", "description": "Room ID", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "period", "in": "query", "description": "Optional billing period in YYYY-MM", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}], "responses": {"200": {"description": "Meter readings for room", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MeterReadingListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/meter-readings/{meter_reading_id}": {"delete": {"tags": ["Billing"], "summary": "Delete meter reading", "description": "Deletes one meter reading from the current organization when it is no longer valid.", "operationId": "delete_meter_reading", "parameters": [{"name": "meter_reading_id", "in": "path", "description": "Meter reading ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Deleted meter reading", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MeterReadingResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Billing"], "summary": "Update meter reading", "description": "Updates one meter reading while preserving period format and non-decreasing meter validation.", "operationId": "update_meter_reading", "parameters": [{"name": "meter_reading_id", "in": "path", "description": "Meter reading ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Meter period and usage values. The API validates YYYY-MM periods and non-decreasing readings.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateMeterReadingRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated meter reading", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MeterReadingResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-accounts": {"get": {"tags": ["Billing"], "summary": "List payment accounts", "description": "Lists bank or manual payment accounts configured for the current organization.", "operationId": "list_payment_accounts", "responses": {"200": {"description": "Payment accounts", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PaymentAccountListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Billing"], "summary": "Create payment account", "description": "Creates a payment account that can be referenced by manual payment collection workflows.", "operationId": "create_payment_account", "requestBody": {"description": "JSON payload used to create payment account.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreatePaymentAccountRequest"}}}, "required": true}, "responses": {"200": {"description": "Created payment account", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PaymentAccountResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-accounts/{payment_account_id}": {"get": {"tags": ["Billing"], "summary": "Get payment account", "description": "Returns one payment account when it belongs to the current organization.", "operationId": "payment_account_detail", "parameters": [{"name": "payment_account_id", "in": "path", "description": "Payment account ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Payment account detail", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PaymentAccountResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "delete": {"tags": ["Billing"], "summary": "Delete payment account", "description": "Deletes a payment account from active use while preserving historical payments.", "operationId": "delete_payment_account", "parameters": [{"name": "payment_account_id", "in": "path", "description": "Payment account ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Deleted payment account", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PaymentAccountResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Billing"], "summary": "Update payment account", "description": "Updates account display and transfer details for a payment account.", "operationId": "update_payment_account", "parameters": [{"name": "payment_account_id", "in": "path", "description": "Payment account ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to update payment account.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdatePaymentAccountRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated payment account", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PaymentAccountResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-banks": {"get": {"tags": ["Billing"], "summary": "List payment banks", "description": "Lists cached VietQR bank reference data for payment account setup. The backend owns upstream fetching, daily cache refresh, and stale fallback so clients do not call VietQR directly.", "operationId": "list_payment_banks", "parameters": [{"name": "provider", "in": "query", "description": "Payment bank provider. Defaults to vietqr.", "required": false, "schema": {"type": "string", "maxLength": 32}}, {"name": "transfer_supported", "in": "query", "description": "When true, return only banks that support VietQR transfers. Defaults to true.", "required": false, "schema": {"type": "boolean"}}, {"name": "search", "in": "query", "description": "Optional case-insensitive search across code, short name, full name, or BIN.", "required": false, "schema": {"type": "string", "maxLength": 80, "minLength": 1}}], "responses": {"200": {"description": "Payment bank directory", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PaymentBankListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "503": {"description": "Bank list unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/invoices": {"get": {"tags": ["Billing"], "summary": "List invoices", "description": "Lists invoices for the current organization with optional property, room, period, status, and overdue filters.", "operationId": "list_invoices", "parameters": [{"name": "property_id", "in": "query", "description": "Filter by property", "required": false, "schema": {"type": "string", "format": "uuid"}}, {"name": "room_id", "in": "query", "description": "Filter by room", "required": false, "schema": {"type": "string", "format": "uuid"}}, {"name": "period", "in": "query", "description": "Filter by an exact billing period (the month the invoice bills for), YYYY-MM. This is a billing month, NOT a calendar-date filter; use due_date_*/issue_date_* for date ranges. Mutually exclusive with period_from/period_to.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_from", "in": "query", "description": "Inclusive lower bound on the billing period (YYYY-MM). Distinct from due_date_*/issue_date_* (calendar dates). Compose with period_to for a billing-month range; cannot be combined with the exact period param.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_to", "in": "query", "description": "Inclusive upper bound on the billing period (YYYY-MM). Distinct from due_date_*/issue_date_* (calendar dates). Compose with period_from for a billing-month range; cannot be combined with the exact period param.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "status", "in": "query", "description": "Filter by invoice status", "required": false, "schema": {"$ref": "#/components/schemas/InvoiceStatus"}}, {"name": "overdue", "in": "query", "description": "Filter overdue invoices", "required": false, "schema": {"type": "boolean"}}, {"name": "search", "in": "query", "description": "Case-insensitive match on invoice number, payment reference, payment code, renter, room, or property name", "required": false, "schema": {"type": "string", "maxLength": 120}}, {"name": "due_date_from", "in": "query", "description": "Inclusive lower bound on due_date (YYYY-MM-DD)", "required": false, "schema": {"type": "string"}}, {"name": "due_date_to", "in": "query", "description": "Inclusive upper bound on due_date (YYYY-MM-DD)", "required": false, "schema": {"type": "string"}}, {"name": "issue_date_from", "in": "query", "description": "Inclusive lower bound on issue_date (YYYY-MM-DD); invoices without an issue date are excluded", "required": false, "schema": {"type": "string"}}, {"name": "issue_date_to", "in": "query", "description": "Inclusive upper bound on issue_date (YYYY-MM-DD); invoices without an issue date are excluded", "required": false, "schema": {"type": "string"}}, {"name": "limit", "in": "query", "description": "Page size 1-500 (default 100)", "required": false, "schema": {"type": "integer", "format": "int64", "maximum": 500, "minimum": 1}}, {"name": "offset", "in": "query", "description": "Page offset (default 0)", "required": false, "schema": {"type": "integer", "format": "int64", "minimum": 0}}], "responses": {"200": {"description": "Invoices", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/InvoiceListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/invoices/generate": {"post": {"tags": ["Billing"], "summary": "Generate invoice", "description": "Generates an invoice for one room and period using rent, utility readings, and configured recurring fees. Idempotent on room and period: a repeated call returns the existing non-cancelled invoice with `already_existed = true` instead of a conflict.", "operationId": "generate_invoice", "requestBody": {"description": "Invoice lifecycle or line-item fields used to update invoice totals and status.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerateInvoiceRequest"}}}, "required": true}, "responses": {"200": {"description": "Generated or existing invoice (idempotent on room and period)", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/GenerateInvoiceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/invoices/generate-bulk": {"post": {"tags": ["Billing"], "summary": "Generate bulk invoices", "description": "Generates invoices for all eligible rooms in a property for one billing period and reports per-room outcomes.", "operationId": "generate_bulk_invoices", "requestBody": {"description": "Invoice lifecycle or line-item fields used to update invoice totals and status.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerateBulkInvoicesRequest"}}}, "required": true}, "responses": {"200": {"description": "Generated invoices for property", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/BulkInvoiceGenerationResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/invoices/{invoice_id}": {"get": {"tags": ["Billing"], "summary": "Get invoice", "description": "Returns one invoice with its lines and payment state when it belongs to the current organization.", "operationId": "invoice_detail", "parameters": [{"name": "invoice_id", "in": "path", "description": "Invoice ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Invoice detail", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/InvoiceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Billing"], "summary": "Update invoice", "description": "Updates editable invoice metadata such as due date and payment reference before or during collection.", "operationId": "update_invoice", "parameters": [{"name": "invoice_id", "in": "path", "description": "Invoice ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Invoice lifecycle or line-item fields used to update invoice totals and status.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateInvoiceRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated invoice", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/InvoiceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/invoices/{invoice_id}/lines": {"get": {"tags": ["Billing"], "summary": "List invoice lines", "description": "Lists invoice line items for an invoice in the current organization.", "operationId": "list_invoice_lines", "parameters": [{"name": "invoice_id", "in": "path", "description": "Invoice ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Invoice lines", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/InvoiceLineListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Billing"], "summary": "Create invoice line", "description": "Adds a manual line item to an invoice and recalculates invoice totals.", "operationId": "create_invoice_line", "parameters": [{"name": "invoice_id", "in": "path", "description": "Invoice ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Invoice lifecycle or line-item fields used to update invoice totals and status.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateInvoiceLineRequest"}}}, "required": true}, "responses": {"200": {"description": "Invoice with created line", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/InvoiceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/invoices/{invoice_id}/issue": {"post": {"tags": ["Billing"], "summary": "Issue invoice", "description": "Moves a draft invoice into the issued lifecycle state for collection.", "operationId": "issue_invoice", "parameters": [{"name": "invoice_id", "in": "path", "description": "Invoice ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Invoice lifecycle or line-item fields used to update invoice totals and status.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/IssueInvoiceRequest"}}}, "required": true}, "responses": {"200": {"description": "Issued invoice", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/InvoiceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/invoices/{invoice_id}/cancel": {"post": {"tags": ["Billing"], "summary": "Cancel invoice", "description": "Cancels an invoice with an optional reason and prevents further normal collection actions.", "operationId": "cancel_invoice", "parameters": [{"name": "invoice_id", "in": "path", "description": "Invoice ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Invoice lifecycle or line-item fields used to update invoice totals and status.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CancelInvoiceRequest"}}}, "required": true}, "responses": {"200": {"description": "Cancelled invoice", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/InvoiceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Invoice has recorded payments or cannot be cancelled in its current status", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/invoices/{invoice_id}/recreate": {"post": {"tags": ["Billing"], "summary": "Recreate invoice", "description": "Documents an AnHome API operation.", "operationId": "recreate_invoice", "parameters": [{"name": "invoice_id", "in": "path", "description": "Invoice ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Replacement draft invoice", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/InvoiceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Invoice has payments or cannot be recreated in its current status", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/invoices/{invoice_id}/mark-overdue": {"post": {"tags": ["Billing"], "summary": "Mark invoice overdue", "description": "Marks an issued invoice overdue when it has passed its due date and remains unpaid.", "operationId": "mark_invoice_overdue", "parameters": [{"name": "invoice_id", "in": "path", "description": "Invoice ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Marked invoice overdue", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/InvoiceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/invoices/{invoice_id}/payments": {"post": {"tags": ["Billing"], "summary": "Record invoice payment", "description": "Records a manual payment against an invoice and updates paid amount and invoice status transactionally.", "operationId": "record_invoice_payment", "parameters": [{"name": "invoice_id", "in": "path", "description": "Invoice ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Manual payment details to apply to the invoice balance.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/RecordPaymentRequest"}}}, "required": true}, "responses": {"200": {"description": "Recorded payment", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PaymentResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/invoice-lines/{line_id}": {"delete": {"tags": ["Billing"], "summary": "Delete invoice line", "description": "Deletes an invoice line item and recalculates invoice totals.", "operationId": "delete_invoice_line", "parameters": [{"name": "line_id", "in": "path", "description": "Invoice line ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Deleted invoice line", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/InvoiceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Billing"], "summary": "Update invoice line", "description": "Updates an invoice line item and recalculates invoice totals with validation for amount and discount rules.", "operationId": "update_invoice_line", "parameters": [{"name": "line_id", "in": "path", "description": "Invoice line ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Invoice lifecycle or line-item fields used to update invoice totals and status.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateInvoiceLineRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated invoice line", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/InvoiceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/invoices/lines/{line_id}": {"post": {"tags": ["Billing"], "summary": "Update invoice line", "description": "Compatibility route for updating an invoice line and recalculating invoice totals.", "operationId": "update_invoice_line_alias", "parameters": [{"name": "line_id", "in": "path", "description": "Invoice line ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Invoice lifecycle or line-item fields used to update invoice totals and status.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateInvoiceLineRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated invoice line", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/InvoiceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payments": {"get": {"tags": ["Billing"], "summary": "List payments", "description": "Lists manual payments recorded for invoices in the current organization, with optional property, room, period, invoice, and method filters plus pagination.", "operationId": "list_payments", "parameters": [{"name": "property_id", "in": "query", "description": "Filter by property (via linked invoice or room)", "required": false, "schema": {"type": "string", "format": "uuid"}}, {"name": "room_id", "in": "query", "description": "Filter by room (payment or linked invoice room)", "required": false, "schema": {"type": "string", "format": "uuid"}}, {"name": "period", "in": "query", "description": "Filter by linked invoice billing period in YYYY-MM", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "invoice_id", "in": "query", "description": "Filter by linked invoice", "required": false, "schema": {"type": "string", "format": "uuid"}}, {"name": "method", "in": "query", "description": "Filter by payment method", "required": false, "schema": {"$ref": "#/components/schemas/PaymentMethod"}}, {"name": "limit", "in": "query", "description": "Page size 1-500 (default 100)", "required": false, "schema": {"type": "integer", "format": "int64", "maximum": 500, "minimum": 1}}, {"name": "offset", "in": "query", "description": "Page offset (default 0)", "required": false, "schema": {"type": "integer", "format": "int64", "minimum": 0}}], "responses": {"200": {"description": "Payments", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PaymentListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payments/{payment_id}": {"patch": {"tags": ["Billing"], "summary": "Update payment", "description": "Updates editable payment metadata such as date, method, amount, and note when allowed by payment state.", "operationId": "update_payment", "parameters": [{"name": "payment_id", "in": "path", "description": "Payment ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to update payment.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdatePaymentRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated payment", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PaymentResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payments/{payment_id}/reverse": {"post": {"tags": ["Billing"], "summary": "Reverse payment", "description": "Reverses a recorded payment, blocks double reversal, and recalculates the linked invoice balance.", "operationId": "reverse_payment", "parameters": [{"name": "payment_id", "in": "path", "description": "Payment ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Reason and optional metadata for reversing a recorded payment.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ReversePaymentRequest"}}}, "required": true}, "responses": {"200": {"description": "Reversed payment", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PaymentResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/accounting/property-room-profitability": {"get": {"tags": ["accounting"], "summary": "Accounting property room profitability", "description": "Returns posted-ledger profitability grouped by property and room for a calendar date range.", "operationId": "accounting_property_room_profitability", "parameters": [{"name": "date_from", "in": "query", "description": "Inclusive journal entry date lower bound in YYYY-MM-DD", "required": true, "schema": {"type": "string"}}, {"name": "date_to", "in": "query", "description": "Inclusive journal entry date upper bound in YYYY-MM-DD", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "Posted-ledger property and room profitability report", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PropertyRoomProfitabilityReport", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/accounting/property-room-profitability.csv": {"get": {"tags": ["accounting"], "summary": "Export accounting property room profitability csv", "description": "Exports posted-ledger profitability grouped by property and room as formula-safe CSV.", "operationId": "export_accounting_property_room_profitability_csv", "parameters": [{"name": "date_from", "in": "query", "description": "Inclusive journal entry date lower bound in YYYY-MM-DD", "required": true, "schema": {"type": "string"}}, {"name": "date_to", "in": "query", "description": "Inclusive journal entry date upper bound in YYYY-MM-DD", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "Posted-ledger property and room profitability CSV", "content": {"text/csv": {"schema": {"type": "string"}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/accounting/property-room-profitability/allocation-preview": {"get": {"tags": ["accounting"], "summary": "Accounting property room profitability allocation preview", "description": "Returns a read-only preview that allocates property-level shared expenses to rooms without posting journal entries.", "operationId": "accounting_property_room_profitability_allocation_preview", "parameters": [{"name": "date_from", "in": "query", "description": "Inclusive journal entry date lower bound in YYYY-MM-DD", "required": true, "schema": {"type": "string"}}, {"name": "date_to", "in": "query", "description": "Inclusive journal entry date upper bound in YYYY-MM-DD", "required": true, "schema": {"type": "string"}}, {"name": "allocation_method", "in": "query", "description": "Shared-expense allocation method. Defaults to revenue_share.", "required": false, "schema": {"$ref": "#/components/schemas/ExpenseAllocationMethod"}}], "responses": {"200": {"description": "Read-only room profitability preview after property-level expense allocation", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PropertyRoomProfitabilityAllocationReport", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/accounting/property-room-profitability/allocation-preview.csv": {"get": {"tags": ["accounting"], "summary": "Export accounting property room profitability allocation preview csv", "description": "Exports the read-only property-level shared expense allocation preview as formula-safe CSV.", "operationId": "export_accounting_property_room_profitability_allocation_preview_csv", "parameters": [{"name": "date_from", "in": "query", "description": "Inclusive journal entry date lower bound in YYYY-MM-DD", "required": true, "schema": {"type": "string"}}, {"name": "date_to", "in": "query", "description": "Inclusive journal entry date upper bound in YYYY-MM-DD", "required": true, "schema": {"type": "string"}}, {"name": "allocation_method", "in": "query", "description": "Shared-expense allocation method. Defaults to revenue_share.", "required": false, "schema": {"$ref": "#/components/schemas/ExpenseAllocationMethod"}}], "responses": {"200": {"description": "Read-only room profitability allocation preview CSV", "content": {"text/csv": {"schema": {"type": "string"}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/dashboard/summary": {"get": {"tags": ["Reports"], "summary": "Dashboard summary", "description": "Returns dashboard totals for a billing period, including receivables, paid amounts, overdue counts, and recent activity. Optionally scoped to one property via `property_id`; organization-wide when omitted.", "operationId": "dashboard_summary", "parameters": [{"name": "period", "in": "query", "description": "Exact billing period in YYYY-MM. Use either period or the closed period_from/period_to range; do not combine them.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_from", "in": "query", "description": "Inclusive billing-period lower bound in YYYY-MM. Must be paired with period_to and cannot be combined with period.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_to", "in": "query", "description": "Inclusive billing-period upper bound in YYYY-MM. Must be paired with period_from and cannot be combined with period.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "property_id", "in": "query", "description": "Optional property filter; organization-wide when omitted", "required": false, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Dashboard summary", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/DashboardSummaryResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/reports/revenue": {"get": {"tags": ["Reports"], "summary": "Revenue report", "description": "Returns revenue report rows for a billing period, optionally filtered by property.", "operationId": "revenue_report", "parameters": [{"name": "period", "in": "query", "description": "Exact billing month in YYYY-MM. Revenue here means collected completed payments by payment_date within the selected month/range, not statutory tax revenue recognition.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_from", "in": "query", "description": "Inclusive month lower bound in YYYY-MM for a closed range. Must be paired with period_to and cannot be combined with period.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_to", "in": "query", "description": "Inclusive month upper bound in YYYY-MM for a closed range. Must be paired with period_from and cannot be combined with period.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "property_id", "in": "query", "description": "Optional property filter", "required": false, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Revenue report with zero-filled period series", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/RevenueReportResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/reports/receivables": {"get": {"tags": ["Reports"], "summary": "Receivables report", "description": "Returns receivables report rows for a billing period, including unpaid and overdue invoice amounts.", "operationId": "receivables_report", "parameters": [{"name": "period", "in": "query", "description": "Exact billing period in YYYY-MM. Use either period or the closed period_from/period_to range; do not combine them.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_from", "in": "query", "description": "Inclusive billing-period lower bound in YYYY-MM. Must be paired with period_to and cannot be combined with period.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_to", "in": "query", "description": "Inclusive billing-period upper bound in YYYY-MM. Must be paired with period_from and cannot be combined with period.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "property_id", "in": "query", "description": "Optional property filter", "required": false, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Receivables report with zero-filled period series", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ReceivablesReportResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/reports/occupancy": {"get": {"tags": ["Reports"], "summary": "Occupancy report", "description": "Returns room occupancy counts and rates, optionally scoped to a property.", "operationId": "occupancy_report", "parameters": [{"name": "property_id", "in": "query", "description": "Optional property filter", "required": false, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Occupancy report", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OccupancyReportResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/exports/invoices.csv": {"get": {"tags": ["Reports"], "summary": "Export invoices csv", "description": "Exports invoice data for a billing period as CSV using the same organization-scoped report rules.", "operationId": "export_invoices_csv", "parameters": [{"name": "period", "in": "query", "description": "Exact billing period in YYYY-MM. Use either period or a closed period_from/period_to range.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_from", "in": "query", "description": "Inclusive billing-period lower bound in YYYY-MM. Must be paired with period_to.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_to", "in": "query", "description": "Inclusive billing-period upper bound in YYYY-MM. Must be paired with period_from.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "property_id", "in": "query", "description": "Optional property filter", "required": false, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Invoices CSV", "content": {"text/csv": {"schema": {"type": "string"}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/exports/payments.csv": {"get": {"tags": ["Reports"], "summary": "Export payments csv", "description": "Exports payment data for a billing period as CSV using the same organization-scoped report rules.", "operationId": "export_payments_csv", "parameters": [{"name": "period", "in": "query", "description": "Exact month in YYYY-MM for payment_date filtering. Use either period or a closed period_from/period_to range.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_from", "in": "query", "description": "Inclusive month lower bound in YYYY-MM for payment_date filtering. Must be paired with period_to.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_to", "in": "query", "description": "Inclusive month upper bound in YYYY-MM for payment_date filtering. Must be paired with period_from.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "property_id", "in": "query", "description": "Optional property filter", "required": false, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Payments CSV", "content": {"text/csv": {"schema": {"type": "string"}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/exports/rooms.csv": {"get": {"tags": ["Reports"], "summary": "Export rooms csv", "description": "Exports active room inventory for the current organization as CSV.", "operationId": "export_rooms_csv", "responses": {"200": {"description": "Rooms CSV", "content": {"text/csv": {"schema": {"type": "string"}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/exports/renters.csv": {"get": {"tags": ["Reports"], "summary": "Export renters csv", "description": "Exports renter profiles for the current organization as CSV.", "operationId": "export_renters_csv", "responses": {"200": {"description": "Renters CSV", "content": {"text/csv": {"schema": {"type": "string"}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/exports/receivables.csv": {"get": {"tags": ["Reports"], "summary": "Export receivables csv", "description": "Exports receivable invoice rows for a billing period as CSV.", "operationId": "export_receivables_csv", "parameters": [{"name": "period", "in": "query", "description": "Exact billing period in YYYY-MM. Use either period or a closed period_from/period_to range.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_from", "in": "query", "description": "Inclusive billing-period lower bound in YYYY-MM. Must be paired with period_to.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_to", "in": "query", "description": "Inclusive billing-period upper bound in YYYY-MM. Must be paired with period_from.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "property_id", "in": "query", "description": "Optional property filter", "required": false, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Receivables CSV", "content": {"text/csv": {"schema": {"type": "string"}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/exports/meter-readings.csv": {"get": {"tags": ["Reports"], "summary": "Export meter readings csv", "description": "Exports meter readings for a billing period as CSV for landlord review or accounting workflows.", "operationId": "export_meter_readings_csv", "parameters": [{"name": "period", "in": "query", "description": "Exact billing period in YYYY-MM. Use either period or a closed period_from/period_to range.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_from", "in": "query", "description": "Inclusive billing-period lower bound in YYYY-MM. Must be paired with period_to.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_to", "in": "query", "description": "Inclusive billing-period upper bound in YYYY-MM. Must be paired with period_from.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "property_id", "in": "query", "description": "Optional property filter", "required": false, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Meter readings CSV", "content": {"text/csv": {"schema": {"type": "string"}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/exports/statement.csv": {"get": {"tags": ["Reports"], "summary": "Export statement csv", "description": "Documents an AnHome API operation.", "operationId": "export_statement_csv", "parameters": [{"name": "period", "in": "query", "description": "Exact statement period in YYYY-MM. This is a management statement export, not a statutory tax invoice/e-invoice.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_from", "in": "query", "description": "Inclusive month lower bound in YYYY-MM. Must be paired with period_to.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "period_to", "in": "query", "description": "Inclusive month upper bound in YYYY-MM. Must be paired with period_from.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "property_id", "in": "query", "description": "Optional property filter", "required": false, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Statement CSV with invoice and payment rows", "content": {"text/csv": {"schema": {"type": "string"}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/imports/rooms": {"post": {"tags": ["Imports"], "summary": "Import rooms", "description": "Imports room inventory rows from a CSV-compatible payload and returns per-row validation results.", "operationId": "import_rooms", "requestBody": {"description": "CSV-compatible import rows. The API returns row-level validation and persistence results.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ImportRoomsRequest"}}}, "required": true}, "responses": {"200": {"description": "Imported rooms from CSV text", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ImportResultResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/imports/renters": {"post": {"tags": ["Imports"], "summary": "Import renters", "description": "Imports renter profile rows from a CSV-compatible payload and returns per-row validation results.", "operationId": "import_renters", "requestBody": {"description": "CSV-compatible import rows. The API returns row-level validation and persistence results.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ImportRentersRequest"}}}, "required": true}, "responses": {"200": {"description": "Imported renters from CSV text", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ImportResultResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/imports/meter-readings": {"post": {"tags": ["Imports"], "summary": "Import meter readings", "description": "Imports meter reading rows for a billing period and returns per-row validation results.", "operationId": "import_meter_readings", "requestBody": {"description": "CSV-compatible import rows. The API returns row-level validation and persistence results.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ImportMeterReadingsRequest"}}}, "required": true}, "responses": {"200": {"description": "Imported meter readings from CSV text", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ImportResultResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/auth/username-availability": {"get": {"tags": ["Authentication"], "summary": "Username availability", "description": "Documents an AnHome API operation.", "operationId": "username_availability", "parameters": [{"name": "username", "in": "query", "description": "Username or phone-number login identifier to check before signup", "required": true, "schema": {"type": "string", "maxLength": 50, "minLength": 3}}], "responses": {"200": {"description": "Username availability for signup onboarding", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/UsernameAvailabilityResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid username query", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/onboarding/setup": {"post": {"tags": ["onboarding"], "summary": "Onboarding setup", "description": "Documents an AnHome API operation.", "operationId": "onboarding_setup", "requestBody": {"description": "JSON payload used to onboarding setup.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/OnboardingSetupRequest"}, "example": {"account": {"display_name": "Demo Owner", "email": "owner@example.com", "password": "change-me-123", "username": "demo_owner"}, "billing_settings": {"billing_day": 1, "due_day": 5, "electricity_pricing_type": "METERED", "electricity_unit_price": "3500", "water_fixed_amount": "15000", "water_pricing_type": "PER_OCCUPANT"}, "organization": {"name": "Demo Boarding House"}, "property": {"address": "123 Nguyen Huu Canh", "city": "Ho Chi Minh", "district": "Binh Thanh", "name": "Demo Property", "ward": "Ward 22"}, "rooms": {"base_rent": "3000000", "count": 3, "default_deposit": "3000000", "name_prefix": "Ph\u00f2ng", "start_number": 1}}}}, "required": true}, "responses": {"200": {"description": "Created landlord account, organization, property, billing settings, rooms, and auth session atomically", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/OnboardingSetupResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid onboarding payload, unsupported electricity pricing, or invalid generated room batch", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Username, email, organization slug, or generated room name already exists; no partial setup is committed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/payment-reconciliation/settings": {"get": {"tags": ["Billing"], "summary": "Get payment reconciliation settings", "description": "Returns payment reconciliation settings for the current organization, including webhook and QR configuration state.", "operationId": "get_payment_reconciliation_settings", "responses": {"200": {"description": "Payment reconciliation settings", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PaymentReconciliationSettingsResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "put": {"tags": ["Billing"], "summary": "Upsert payment reconciliation settings", "description": "Creates or updates organization-level payment reconciliation settings used by QR and bank-transfer matching.", "operationId": "upsert_payment_reconciliation_settings", "requestBody": {"description": "Payment reconciliation settings, webhook secret configuration, and QR transfer account details.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpsertPaymentReconciliationSettingsRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated payment reconciliation settings", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PaymentReconciliationSettingsResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-reconciliation/invoices/{invoice_id}/qr": {"get": {"tags": ["Billing"], "summary": "Payment reconciliation invoice qr", "description": "Returns a tenant-facing invoice payment QR payload generated from the organization's reconciliation settings.", "operationId": "payment_reconciliation_invoice_qr", "parameters": [{"name": "invoice_id", "in": "path", "description": "Invoice ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Invoice QR payload for bank transfer", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/InvoiceQrResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-reconciliation/matches": {"post": {"tags": ["Billing"], "summary": "Match reconciled payment", "description": "Manually matches a reconciled bank-transfer event to an invoice payment when automatic matching needs review.", "operationId": "match_reconciled_payment", "requestBody": {"description": "Manual reconciliation decision linking a reviewed bank-transfer event to an invoice.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MatchPaymentRequest"}}}, "required": true}, "responses": {"200": {"description": "Recorded a reconciled bank transfer payment", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MatchPaymentResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-reconciliation/review-items": {"get": {"tags": ["Billing"], "summary": "List payment review items", "description": "Documents an AnHome API operation.", "operationId": "list_payment_review_items", "parameters": [{"name": "status", "in": "query", "description": "Review status; defaults to NEEDS_REVIEW", "required": false, "schema": {"$ref": "#/components/schemas/ReviewItemStatus"}}, {"name": "property_id", "in": "query", "description": "Property scope", "required": false, "schema": {"type": "string", "format": "uuid"}}, {"name": "failure_reason", "in": "query", "description": "System failure classification", "required": false, "schema": {"type": "string", "maxLength": 80}}, {"name": "received_from", "in": "query", "description": "First received date, YYYY-MM-DD", "required": false, "schema": {"type": "string"}}, {"name": "received_to", "in": "query", "description": "Last received date, YYYY-MM-DD", "required": false, "schema": {"type": "string"}}, {"name": "limit", "in": "query", "description": "Page size 1-500 (default 100)", "required": false, "schema": {"type": "integer", "format": "int64", "maximum": 500, "minimum": 1}}, {"name": "offset", "in": "query", "description": "Page offset (default 0)", "required": false, "schema": {"type": "integer", "format": "int64", "minimum": 0}}], "responses": {"200": {"description": "Payment review queue", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ReviewItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-reconciliation/review-items/{review_item_id}/match": {"post": {"tags": ["Billing"], "summary": "Match payment review item", "description": "Documents an AnHome API operation.", "operationId": "match_payment_review_item", "parameters": [{"name": "review_item_id", "in": "path", "description": "Payment review item ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to match payment review item.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/MatchReviewItemRequest"}}}, "required": true}, "responses": {"200": {"description": "Matched review item and payment", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MatchReviewItemResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-reconciliation/review-items/{review_item_id}/ignore": {"post": {"tags": ["Billing"], "summary": "Ignore payment review item", "description": "Documents an AnHome API operation.", "operationId": "ignore_payment_review_item", "parameters": [{"name": "review_item_id", "in": "path", "description": "Payment review item ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to ignore payment review item.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResolveReviewItemRequest"}}}, "required": true}, "responses": {"200": {"description": "Ignored review item", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ReviewItemResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-reconciliation/review-items/{review_item_id}/mark-resolved": {"post": {"tags": ["Billing"], "summary": "Resolve payment review item", "description": "Documents an AnHome API operation.", "operationId": "resolve_payment_review_item", "parameters": [{"name": "review_item_id", "in": "path", "description": "Payment review item ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to resolve payment review item.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ResolveReviewItemRequest"}}}, "required": true}, "responses": {"200": {"description": "Externally resolved review item", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ReviewItemResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-reconciliation/bank-hub/status": {"get": {"tags": ["Billing"], "summary": "Bank hub status", "description": "Documents an AnHome API operation.", "operationId": "bank_hub_status", "responses": {"200": {"description": "SePay Bank Hub connection status", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/BankHubStatusResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-reconciliation/bank-hub/link-token": {"post": {"tags": ["Billing"], "summary": "Create bank hub link token", "description": "Documents an AnHome API operation.", "operationId": "create_bank_hub_link_token", "responses": {"200": {"description": "Created one-time SePay Hosted Link", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/BankHubLinkTokenResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-reconciliation/bank-hub/accounts/{payment_account_id}/link-token": {"post": {"tags": ["Billing"], "summary": "Create bank hub account link token", "description": "Documents an AnHome API operation.", "operationId": "create_bank_hub_account_link_token", "parameters": [{"name": "payment_account_id", "in": "path", "description": "Payment account ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Created one-time SePay Hosted Link for verifying this account", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/BankHubLinkTokenResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Payment account identity is incomplete", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Payment account is already linked", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-reconciliation/bank-hub/accounts/{payment_account_id}/verify": {"post": {"tags": ["Billing"], "summary": "Verify bank hub payment account", "description": "Documents an AnHome API operation.", "operationId": "verify_bank_hub_payment_account", "parameters": [{"name": "payment_account_id", "in": "path", "description": "Payment account ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Verified and linked the selected payment account", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PaymentAccountResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Bank identity is missing, mismatched, or ambiguous", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "503": {"description": "SePay Bank Hub is unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-reconciliation/bank-hub/accounts/{payment_account_id}/unlink-token": {"post": {"tags": ["Billing"], "summary": "Create bank hub unlink token", "description": "Documents an AnHome API operation.", "operationId": "create_bank_hub_unlink_token", "parameters": [{"name": "payment_account_id", "in": "path", "description": "Payment account ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Created one-time SePay Hosted Link for unlinking", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/BankHubLinkTokenResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Payment account not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Bank Hub account state is missing or stale", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "503": {"description": "SePay Bank Hub is unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-reconciliation/bank-hub/accounts/{payment_account_id}/reactivate-token": {"post": {"tags": ["Billing"], "summary": "Create bank hub reactivate token", "description": "Documents an AnHome API operation.", "operationId": "create_bank_hub_reactivate_token", "parameters": [{"name": "payment_account_id", "in": "path", "description": "Payment account ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Created one-time SePay Hosted Link for reactivation", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/BankHubLinkTokenResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Payment account not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Bank Hub account state is missing or stale", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "503": {"description": "SePay Bank Hub is unavailable", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/payment-reconciliation/bank-hub/sync": {"post": {"tags": ["Billing"], "summary": "Sync bank hub", "description": "Documents an AnHome API operation.", "operationId": "sync_bank_hub", "responses": {"200": {"description": "Synchronized linked SePay bank accounts", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/BankHubStatusResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Bank Hub account cannot be matched safely", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/webhooks/sepay/bank-hub/ipn": {"post": {"tags": ["Billing"], "summary": "Bank hub ipn", "description": "Documents an AnHome API operation.", "operationId": "bank_hub_ipn", "responses": {"200": {"description": "Acknowledged SePay Bank Hub balance notification", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SepayWebhookAck"}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "503": {"description": "Bank Hub notification must be retried", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"sepayBankHubApiKey": []}]}}, "/api/v1/public/sepay/bank-hub/completion": {"get": {"tags": ["Billing"], "summary": "Bank hub completion", "description": "Documents an AnHome API operation.", "operationId": "bank_hub_completion", "responses": {"200": {"description": "SePay Hosted Link completion page", "content": {"text/html": {"schema": {"type": "string"}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/webhooks/sepay/{webhook_public_id}": {"post": {"tags": ["Billing"], "summary": "Sepay webhook", "description": "Accepts signed SePay webhook events for one organization and records idempotent invoice payments or review events.", "operationId": "sepay_webhook", "parameters": [{"name": "webhook_public_id", "in": "path", "description": "Organization-scoped SePay webhook public ID", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "Acknowledged SePay webhook", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SepayWebhookAck"}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/invoices/{invoice_id}/tenant-link": {"post": {"tags": ["Billing"], "summary": "Create tenant invoice link", "description": "Creates a tokenized public invoice link so a tenant can view invoice and payment details without account auth.", "operationId": "create_tenant_invoice_link", "parameters": [{"name": "invoice_id", "in": "path", "description": "Invoice ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Created tenant-safe public invoice link", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantInvoiceLinkResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant-portal/invoices/{public_token}": {"get": {"tags": ["Tenant Portal"], "summary": "Tenant portal public invoice", "description": "Returns a tenant-facing invoice view for a valid public invoice token.", "operationId": "tenant_portal_public_invoice", "parameters": [{"name": "public_token", "in": "path", "description": "Public invoice token", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "Public tenant invoice view", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantPortalInvoiceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/tenant-portal/invoices/{public_token}/maintenance-tickets": {"post": {"tags": ["Tenant Portal"], "summary": "Tenant portal create maintenance ticket", "description": "Creates a tenant-submitted maintenance request from a public invoice link.", "operationId": "tenant_portal_create_maintenance_ticket", "parameters": [{"name": "public_token", "in": "path", "description": "Public invoice token", "required": true, "schema": {"type": "string"}}], "requestBody": {"description": "Maintenance request details, priority, room context, and tenant/operator notes.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantMaintenanceTicketRequest"}}}, "required": true}, "responses": {"200": {"description": "Created tenant maintenance ticket", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantMaintenanceTicketResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/maintenance-tickets": {"get": {"tags": ["Maintenance"], "summary": "List maintenance tickets", "description": "Lists maintenance tickets for the current organization with optional status and room filters.", "operationId": "list_maintenance_tickets", "parameters": [{"name": "property_id", "in": "query", "description": "Optional property filter", "required": false, "schema": {"type": "string", "format": "uuid"}}, {"name": "room_id", "in": "query", "description": "Optional room filter", "required": false, "schema": {"type": "string", "format": "uuid"}}, {"name": "status", "in": "query", "description": "Optional status filter", "required": false, "schema": {"$ref": "#/components/schemas/MaintenanceTicketStatus"}}], "responses": {"200": {"description": "Maintenance tickets", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MaintenanceTicketListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Maintenance"], "summary": "Create maintenance ticket", "description": "Creates an organization-scoped maintenance ticket for a renter, room, or operator-reported issue.", "operationId": "create_maintenance_ticket", "requestBody": {"description": "Maintenance request details, priority, room context, and tenant/operator notes.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateMaintenanceTicketRequest"}}}, "required": true}, "responses": {"200": {"description": "Created maintenance ticket", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MaintenanceTicketResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/maintenance-tickets/{ticket_id}": {"get": {"tags": ["Maintenance"], "summary": "Maintenance ticket detail", "description": "Returns one maintenance ticket when it belongs to the current organization.", "operationId": "maintenance_ticket_detail", "parameters": [{"name": "ticket_id", "in": "path", "description": "Maintenance ticket ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Maintenance ticket detail", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MaintenanceTicketResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Maintenance"], "summary": "Update maintenance ticket", "description": "Updates maintenance ticket status, priority, assignment, or resolution details.", "operationId": "update_maintenance_ticket", "parameters": [{"name": "ticket_id", "in": "path", "description": "Maintenance ticket ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "Maintenance ticket status, priority, assignment, and resolution updates.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateMaintenanceTicketRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated maintenance ticket", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MaintenanceTicketResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/auth/admin/login": {"post": {"tags": ["platform_auth"], "summary": "Admin login", "description": "Documents an AnHome API operation.", "operationId": "admin_login", "requestBody": {"description": "JSON payload used to admin login.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AdminLoginRequest"}}}, "required": true}, "responses": {"200": {"description": "Platform session or MFA challenge", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/AdminLoginResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Invalid credentials", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limited", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/auth/admin/mfa/verify": {"post": {"tags": ["platform_auth"], "summary": "Admin mfa verify", "description": "Documents an AnHome API operation.", "operationId": "admin_mfa_verify", "requestBody": {"description": "JSON payload used to admin mfa verify.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AdminMfaVerifyRequest"}}}, "required": true}, "responses": {"200": {"description": "Platform session", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/AdminSessionResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Invalid or replayed MFA proof", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limited", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/auth/admin/refresh": {"post": {"tags": ["platform_auth"], "summary": "Admin refresh", "description": "Documents an AnHome API operation.", "operationId": "admin_refresh", "responses": {"200": {"description": "Rotated platform session", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/AdminSessionResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Missing, expired, revoked, or replayed refresh cookie", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limited", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/auth/admin/logout": {"post": {"tags": ["platform_auth"], "summary": "Admin logout", "description": "Documents an AnHome API operation.", "operationId": "admin_logout", "responses": {"200": {"description": "Platform session revoked and cookie cleared", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MessageResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/auth/admin/step-up": {"post": {"tags": ["platform_auth"], "summary": "Admin step up", "description": "Documents an AnHome API operation.", "operationId": "admin_step_up", "requestBody": {"description": "JSON payload used to admin step up.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/StepUpRequest"}}}, "required": true}, "responses": {"200": {"description": "Five-minute single-use scoped action token", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/StepUpResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Invalid password or MFA proof", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limited", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/auth/account-actions/inspect": {"post": {"tags": ["platform_auth"], "summary": "Account action inspect", "description": "Documents an AnHome API operation.", "operationId": "account_action_inspect", "requestBody": {"description": "JSON payload used to account action inspect.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AccountActionInspectRequest"}}}, "required": true}, "responses": {"200": {"description": "Inspected one-time account action without exposing token in the URL", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/AccountActionInspectResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid, expired, or used token", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limited", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/auth/account-actions/complete": {"post": {"tags": ["platform_auth"], "summary": "Account action complete", "description": "Documents an AnHome API operation.", "operationId": "account_action_complete", "requestBody": {"description": "JSON payload used to account action complete.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AccountActionCompleteRequest"}}}, "required": true}, "responses": {"200": {"description": "Completed setup, reset, or verification exactly once", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/AccountActionCompleteResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid, expired, or used token", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limited", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/platform/ops/me": {"get": {"tags": ["Operations"], "summary": "Me", "description": "Documents an AnHome API operation.", "operationId": "ops_me", "responses": {"200": {"description": "Current platform principal and session state", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/me/password": {"patch": {"tags": ["Operations"], "summary": "Change password", "description": "Documents an AnHome API operation.", "operationId": "ops_change_password", "requestBody": {"description": "JSON payload used to change password.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ChangePlatformPasswordRequest"}}}, "required": true}, "responses": {"200": {"description": "Changed platform password and revoked other sessions", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MessageResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/me/mfa": {"post": {"tags": ["Operations"], "summary": "Begin mfa", "description": "Documents an AnHome API operation.", "operationId": "ops_begin_mfa", "responses": {"200": {"description": "Started MFA enrollment; secret is returned once", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MfaEnrollmentResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "MFA is already enabled", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "delete": {"tags": ["Operations"], "summary": "Disable mfa", "description": "Documents an AnHome API operation.", "operationId": "ops_disable_mfa", "requestBody": {"description": "JSON payload used to disable mfa.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/DisableMfaRequest"}}}, "required": true}, "responses": {"200": {"description": "Disabled MFA using a scoped step-up token", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MessageResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/me/mfa/confirm": {"post": {"tags": ["Operations"], "summary": "Confirm mfa", "description": "Documents an AnHome API operation.", "operationId": "ops_confirm_mfa", "requestBody": {"description": "JSON payload used to confirm mfa.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ConfirmMfaRequest"}}}, "required": true}, "responses": {"200": {"description": "Confirmed TOTP and returned one-time recovery codes", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MfaConfirmResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/dashboard": {"get": {"tags": ["Operations"], "summary": "Dashboard", "description": "Documents an AnHome API operation.", "operationId": "ops_dashboard", "parameters": [{"name": "range", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Platform operations dashboard", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/landlords": {"get": {"tags": ["Operations"], "summary": "List landlords", "description": "Documents an AnHome API operation.", "operationId": "ops_list_landlords", "parameters": [{"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Masked landlord list", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Operations"], "summary": "Create landlord", "description": "Documents an AnHome API operation.", "operationId": "ops_create_landlord", "requestBody": {"description": "JSON payload used to create landlord.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateLandlordRequest"}}}, "required": true}, "responses": {"200": {"description": "Landlord, initial organization, and one-time setup link", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/landlords/{landlord_id}": {"get": {"tags": ["Operations"], "summary": "Landlord detail", "description": "Documents an AnHome API operation.", "operationId": "ops_landlord_detail", "parameters": [{"name": "landlord_id", "in": "path", "description": "Landlord ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Masked landlord support detail", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/landlords/{landlord_id}/status": {"patch": {"tags": ["Operations"], "summary": "Update landlord status", "description": "Documents an AnHome API operation.", "operationId": "ops_update_landlord_status", "parameters": [{"name": "landlord_id", "in": "path", "description": "Landlord ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to update landlord status.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateStatusRequest"}}}, "required": true}, "responses": {"200": {"description": "Suspended or restored landlord", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/landlords/{landlord_id}/sessions": {"get": {"tags": ["Operations"], "summary": "Landlord sessions", "description": "Documents an AnHome API operation.", "operationId": "ops_landlord_sessions", "parameters": [{"name": "landlord_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Landlord sessions without token material", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "delete": {"tags": ["Operations"], "summary": "Revoke landlord sessions", "description": "Documents an AnHome API operation.", "operationId": "ops_revoke_landlord_sessions", "parameters": [{"name": "landlord_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to revoke landlord sessions.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SensitiveActionRequest"}}}, "required": true}, "responses": {"200": {"description": "Revoked all landlord sessions", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/landlords/{landlord_id}/sessions/{session_id}": {"delete": {"tags": ["Operations"], "summary": "Revoke landlord session", "description": "Documents an AnHome API operation.", "operationId": "ops_revoke_landlord_session", "parameters": [{"name": "landlord_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "session_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to revoke landlord session.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SensitiveActionRequest"}}}, "required": true}, "responses": {"200": {"description": "Revoked one landlord session", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/landlords/{landlord_id}/devices": {"get": {"tags": ["Operations"], "summary": "Landlord devices", "description": "Documents an AnHome API operation.", "operationId": "ops_landlord_devices", "parameters": [{"name": "landlord_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Landlord devices without push tokens", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "delete": {"tags": ["Operations"], "summary": "Revoke landlord devices", "description": "Documents an AnHome API operation.", "operationId": "ops_revoke_landlord_devices", "parameters": [{"name": "landlord_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to revoke landlord devices.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SensitiveActionRequest"}}}, "required": true}, "responses": {"200": {"description": "Revoked all landlord devices", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/landlords/{landlord_id}/devices/{device_id}": {"delete": {"tags": ["Operations"], "summary": "Revoke landlord device", "description": "Documents an AnHome API operation.", "operationId": "ops_revoke_landlord_device", "parameters": [{"name": "landlord_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "device_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to revoke landlord device.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SensitiveActionRequest"}}}, "required": true}, "responses": {"200": {"description": "Revoked one landlord device", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/landlords/{landlord_id}/account-actions": {"post": {"tags": ["Operations"], "summary": "Landlord account action", "description": "Documents an AnHome API operation.", "operationId": "ops_landlord_account_action", "parameters": [{"name": "landlord_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to landlord account action.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerateAccountLinkRequest"}}}, "required": true}, "responses": {"200": {"description": "Created a one-time setup, reset, or verification link", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/pii-reveals": {"post": {"tags": ["Operations"], "summary": "Reveal pii", "description": "Documents an AnHome API operation.", "operationId": "ops_reveal_pii", "requestBody": {"description": "JSON payload used to reveal pii.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/PiiRevealRequest"}}}, "required": true}, "responses": {"200": {"description": "Audited field-level PII reveal", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations": {"get": {"tags": ["Operations"], "summary": "List organizations", "description": "Lists organizations for internal support with optional status, plan, and text search filters.", "operationId": "ops_list_organizations", "parameters": [{"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Organization list with usage and quota", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}": {"get": {"tags": ["Operations"], "summary": "Organization detail", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_detail", "parameters": [{"name": "organization_id", "in": "path", "description": "Organization ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Organization detail", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/status": {"patch": {"tags": ["Operations"], "summary": "Update organization status", "description": "Suspends or restores an organization status through the internal support workflow and writes an audit record.", "operationId": "ops_update_organization_status", "parameters": [{"name": "organization_id", "in": "path", "description": "Organization ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to update organization status.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateStatusRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated organization status", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/plan": {"patch": {"tags": ["Operations"], "summary": "Update organization plan", "description": "Documents an AnHome API operation.", "operationId": "ops_update_organization_plan", "parameters": [{"name": "organization_id", "in": "path", "description": "Organization ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to update organization plan.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdatePlanRequest"}}}, "required": true}, "responses": {"200": {"description": "Assigned fixed plan or quota conflict", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/members": {"get": {"tags": ["Operations"], "summary": "Organization members", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_members", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Organization memberships", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Operations"], "summary": "Add organization member", "description": "Documents an AnHome API operation.", "operationId": "ops_add_organization_member", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to add organization member.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/AddMembershipRequest"}}}, "required": true}, "responses": {"200": {"description": "Added organization membership", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/members/{membership_id}": {"delete": {"tags": ["Operations"], "summary": "Remove organization member", "description": "Documents an AnHome API operation.", "operationId": "ops_remove_organization_member", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "membership_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to remove organization member.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateMembershipRequest"}}}, "required": true}, "responses": {"200": {"description": "Removed organization membership with last-owner guard", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Operations"], "summary": "Update organization member", "description": "Documents an AnHome API operation.", "operationId": "ops_update_organization_member", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "membership_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to update organization member.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdateMembershipRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated organization membership", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/properties": {"get": {"tags": ["Operations"], "summary": "Organization properties", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_properties", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Read-only properties", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/rooms": {"get": {"tags": ["Operations"], "summary": "Organization rooms", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_rooms", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Read-only rooms", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/room-history": {"get": {"tags": ["Operations"], "summary": "Organization room history", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_room_history", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Read-only room history", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/renters": {"get": {"tags": ["Operations"], "summary": "Organization renters", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_renters", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Masked renters", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/leases": {"get": {"tags": ["Operations"], "summary": "Organization leases", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_leases", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Read-only leases", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/billing-settings": {"get": {"tags": ["Operations"], "summary": "Organization billing settings", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_billing_settings", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Read-only billing settings", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/fee-templates": {"get": {"tags": ["Operations"], "summary": "Organization fee templates", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_fee_templates", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Read-only fee templates", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/meter-readings": {"get": {"tags": ["Operations"], "summary": "Organization meter readings", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_meter_readings", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Read-only meter readings", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/invoices": {"get": {"tags": ["Operations"], "summary": "Organization invoices", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_invoices", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Read-only invoice lifecycle and lines", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/payments": {"get": {"tags": ["Operations"], "summary": "Organization payments", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_payments", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Read-only payment and reversal history", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/payment-accounts": {"get": {"tags": ["Operations"], "summary": "Organization payment accounts", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_payment_accounts", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Masked payment accounts without QR payloads", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/reconciliation": {"get": {"tags": ["Operations"], "summary": "Organization reconciliation", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_reconciliation", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Sanitized reconciliation status and review queue", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/reports": {"get": {"tags": ["Operations"], "summary": "Organization reports", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_reports", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Read-only report summary", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/accounting": {"get": {"tags": ["Operations"], "summary": "Organization accounting", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_accounting", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Read-only accounting aggregates", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/imports": {"get": {"tags": ["Operations"], "summary": "Organization imports", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_imports", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Sanitized import history when available", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/maintenance": {"get": {"tags": ["Operations"], "summary": "Organization maintenance", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_maintenance", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Read-only maintenance tickets", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/listings": {"get": {"tags": ["Operations"], "summary": "Organization listings", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_listings", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Read-only listing and image metadata", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/inquiries": {"get": {"tags": ["Operations"], "summary": "Organization inquiries", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_inquiries", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Read-only inquiry metadata", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/organizations/{organization_id}/domain-audit": {"get": {"tags": ["Operations"], "summary": "Organization domain audit", "description": "Documents an AnHome API operation.", "operationId": "ops_organization_domain_audit", "parameters": [{"name": "organization_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Redacted domain audit", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/plans": {"get": {"tags": ["Operations"], "summary": "List plans", "description": "Documents an AnHome API operation.", "operationId": "ops_list_plans", "responses": {"200": {"description": "Fixed AnHome plans and usage", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/platform-admins": {"get": {"tags": ["Operations"], "summary": "List platform users", "description": "Documents an AnHome API operation.", "operationId": "ops_list_platform_users", "parameters": [{"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Platform staff list", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Operations"], "summary": "Create platform user", "description": "Documents an AnHome API operation.", "operationId": "ops_create_platform_user", "requestBody": {"description": "JSON payload used to create platform user.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreatePlatformUserRequest"}}}, "required": true}, "responses": {"200": {"description": "Platform staff and one-time setup link", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/platform-admins/{platform_user_id}": {"patch": {"tags": ["Operations"], "summary": "Update platform user", "description": "Documents an AnHome API operation.", "operationId": "ops_update_platform_user", "parameters": [{"name": "platform_user_id", "in": "path", "description": "Platform user ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to update platform user.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpdatePlatformUserRequest"}}}, "required": true}, "responses": {"200": {"description": "Updated platform staff role or status", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/platform-admins/{platform_user_id}/account-actions": {"post": {"tags": ["Operations"], "summary": "Platform user account action", "description": "Documents an AnHome API operation.", "operationId": "ops_platform_user_account_action", "parameters": [{"name": "platform_user_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to platform user account action.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/GenerateAccountLinkRequest"}}}, "required": true}, "responses": {"200": {"description": "Created a one-time platform staff setup or reset link", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/platform-admins/{platform_user_id}/sessions": {"get": {"tags": ["Operations"], "summary": "Platform user sessions", "description": "Documents an AnHome API operation.", "operationId": "ops_platform_user_sessions", "parameters": [{"name": "platform_user_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Platform staff sessions without token material", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "delete": {"tags": ["Operations"], "summary": "Revoke platform user sessions", "description": "Documents an AnHome API operation.", "operationId": "ops_revoke_platform_user_sessions", "parameters": [{"name": "platform_user_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to revoke platform user sessions.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SensitiveActionRequest"}}}, "required": true}, "responses": {"200": {"description": "Revoked platform staff sessions", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/platform-admins/{platform_user_id}/mfa": {"delete": {"tags": ["Operations"], "summary": "Reset platform user mfa", "description": "Documents an AnHome API operation.", "operationId": "ops_reset_platform_user_mfa", "parameters": [{"name": "platform_user_id", "in": "path", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to reset platform user mfa.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/SensitiveActionRequest"}}}, "required": true}, "responses": {"200": {"description": "Reset platform staff MFA", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/audit-logs": {"get": {"tags": ["Operations"], "summary": "List audit logs", "description": "Lists audit log entries across organizations for internal support investigations.", "operationId": "ops_list_audit_logs", "parameters": [{"name": "cursor", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "limit", "in": "path", "required": true, "schema": {"type": ["integer", "null"], "format": "int64"}}, {"name": "q", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "status", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "plan_code", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "role", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "action", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}, {"name": "resource_type", "in": "path", "required": true, "schema": {"type": ["string", "null"]}}], "responses": {"200": {"description": "Redacted platform audit rows", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ItemListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/platform/ops/system-health": {"get": {"tags": ["Operations"], "summary": "System health", "description": "Documents an AnHome API operation.", "operationId": "ops_system_health", "responses": {"200": {"description": "Sanitized system and provider readiness", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/public/listings": {"get": {"tags": ["public_listings"], "summary": "List public listings", "description": "Documents an AnHome API operation.", "operationId": "list_public_listings", "parameters": [{"name": "q", "in": "query", "description": "Keyword over headline/description/property/room", "required": false, "schema": {"type": "string"}}, {"name": "city", "in": "query", "description": "Exact city filter", "required": false, "schema": {"type": "string"}}, {"name": "district", "in": "query", "description": "Exact district filter", "required": false, "schema": {"type": "string"}}, {"name": "ward", "in": "query", "description": "Exact ward filter", "required": false, "schema": {"type": "string"}}, {"name": "province_code", "in": "query", "description": "Official province code (issue #29); applied after resolving each listing's legacy location to the 2-tier model", "required": false, "schema": {"type": "string", "maxLength": 20}}, {"name": "ward_code", "in": "query", "description": "Official ward code (issue #29); same resolution as province_code", "required": false, "schema": {"type": "string", "maxLength": 20}}, {"name": "amenity", "in": "query", "description": "Single amenity filter", "required": false, "schema": {"type": "string"}}, {"name": "min_rent", "in": "query", "description": "Minimum monthly rent as a decimal string (ADR 0008)", "required": false, "schema": {"type": "string"}}, {"name": "max_rent", "in": "query", "description": "Maximum monthly rent as a decimal string (ADR 0008)", "required": false, "schema": {"type": "string"}}, {"name": "min_area", "in": "query", "description": "Minimum area in m2", "required": false, "schema": {"type": "number", "format": "double"}}, {"name": "max_area", "in": "query", "description": "Maximum area in m2", "required": false, "schema": {"type": "number", "format": "double"}}, {"name": "available_on", "in": "query", "description": "Available on or before this YYYY-MM-DD date", "required": false, "schema": {"type": "string"}}], "responses": {"200": {"description": "Public vacant-room listings", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PublicListingListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid official-code filter", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/public/listings/{slug}": {"get": {"tags": ["public_listings"], "summary": "Public listing detail", "description": "Documents an AnHome API operation.", "operationId": "public_listing_detail", "parameters": [{"name": "slug", "in": "path", "description": "Listing slug", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "Public listing detail", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PublicListingResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Listing is not public", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/public/listings/{slug}/inquiries": {"post": {"tags": ["public_listings"], "summary": "Create listing inquiry", "description": "Documents an AnHome API operation.", "operationId": "create_listing_inquiry", "parameters": [{"name": "slug", "in": "path", "description": "Listing slug", "required": true, "schema": {"type": "string"}}], "requestBody": {"description": "JSON payload used to create listing inquiry.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateListingInquiryRequest"}}}, "required": true}, "responses": {"200": {"description": "Recorded inquiry", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/PublicInquiryAck", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Listing is not public", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/public/vn-administrative-units": {"get": {"tags": ["public_listings"], "summary": "List admin units", "description": "Documents an AnHome API operation.", "operationId": "list_admin_units", "parameters": [{"name": "level", "in": "query", "description": "province or ward; both levels when omitted. For public search preselect, call level=province with lat/lng and limit=1, then use data.units[0].code as province_code.", "required": false, "schema": {"type": "string"}}, {"name": "parent_code", "in": "query", "description": "Parent province code; with level=ward, returns that province's wards. For ward preselect, call level=ward with parent_code plus the same lat/lng and limit=1, then use data.units[0].code only when the ward exists in public filter options.", "required": false, "schema": {"type": "string", "maxLength": 20}}, {"name": "q", "in": "query", "description": "Case-insensitive name search (vi or en)", "required": false, "schema": {"type": "string", "maxLength": 100}}, {"name": "lat", "in": "query", "description": "Browser latitude for nearest-ranking and public search location preselect; must be paired with lng", "required": false, "schema": {"type": "number", "format": "double"}}, {"name": "lng", "in": "query", "description": "Browser longitude for nearest-ranking and public search location preselect; must be paired with lat", "required": false, "schema": {"type": "number", "format": "double"}}, {"name": "limit", "in": "query", "description": "Page size 1-200 (default 100). Use limit=1 for nearest province/ward preselect.", "required": false, "schema": {"type": "integer", "format": "int64", "maximum": 200, "minimum": 1}}], "responses": {"200": {"description": "Vietnam 2-tier (2025) administrative units, localized to Accept-Language. With lat/lng, results are nearest-ranked; public clients may use units[0].code as the dropdown preselect value.", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/AdminUnitListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid location query", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/public/listing-filter-options": {"get": {"tags": ["public_listings"], "summary": "List filter options", "description": "Documents an AnHome API operation.", "operationId": "list_filter_options", "parameters": [{"name": "province_code", "in": "query", "description": "Scope returned wards/amenities to one province", "required": false, "schema": {"type": "string"}}], "responses": {"200": {"description": "Vacancy filter options (provinces + wards + amenities) derived only from publicly-visible listings, with counts", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ListingFilterOptionsResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/rooms/{room_id}/listing": {"get": {"tags": ["public_listings"], "summary": "Admin get room listing", "description": "Documents an AnHome API operation.", "operationId": "admin_get_room_listing", "parameters": [{"name": "room_id", "in": "path", "description": "Room ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Room listing (admin view)", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/AdminListingResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "No listing for this room", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "put": {"tags": ["public_listings"], "summary": "Admin upsert room listing", "description": "Documents an AnHome API operation.", "operationId": "admin_upsert_room_listing", "parameters": [{"name": "room_id", "in": "path", "description": "Room ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON payload used to admin upsert room listing.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/UpsertListingRequest"}}}, "required": true}, "responses": {"200": {"description": "Created or updated room listing", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/AdminListingResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/rooms/{room_id}/listing/publish": {"post": {"tags": ["public_listings"], "summary": "Admin publish room listing", "description": "Documents an AnHome API operation.", "operationId": "admin_publish_room_listing", "parameters": [{"name": "room_id", "in": "path", "description": "Room ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Published room listing", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/AdminListingResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/rooms/{room_id}/listing/unpublish": {"post": {"tags": ["public_listings"], "summary": "Admin unpublish room listing", "description": "Documents an AnHome API operation.", "operationId": "admin_unpublish_room_listing", "parameters": [{"name": "room_id", "in": "path", "description": "Room ID", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Unpublished room listing", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/AdminListingResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/listing-inquiries": {"get": {"tags": ["public_listings"], "summary": "List listing inquiries", "description": "Documents an AnHome API operation.", "operationId": "list_listing_inquiries", "responses": {"200": {"description": "Listing inquiries for the organization", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/ListingInquiryListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/media/uploads": {"post": {"tags": ["media"], "summary": "Upload media", "description": "Documents an AnHome API operation.", "operationId": "upload_media", "requestBody": {"description": "Multipart form with fields: file (JPEG, PNG, or WebP), purpose=room_listing_image, entity_type=room, and entity_id=<room UUID>.", "content": {"multipart/form-data": {"schema": {"$ref": "#/components/schemas/MediaUploadRequest"}}}, "required": true}, "responses": {"200": {"description": "Uploaded media asset with CDN URL", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/MediaUploadResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid media upload, unsupported content type, or asset/room mismatch", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Missing or invalid bearer token", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Caller lacks room-management permission", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/labels": {"get": {"tags": ["labels"], "summary": "Labels", "description": "Documents an AnHome API operation.", "operationId": "labels", "responses": {"200": {"description": "Localized domain enum label dictionaries and form options", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/LabelsResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/tenant/auth/register": {"post": {"tags": ["Tenant"], "summary": "Register tenant account", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_register", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_register`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantRegisterRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAuthResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/tenant/auth/login": {"post": {"tags": ["Tenant"], "summary": "Log in tenant", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_login", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_login`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantLoginRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAuthResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Invalid tenant login payload", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Invalid tenant credentials; response error.code is invalid_credentials", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/tenant/auth/refresh": {"post": {"tags": ["Tenant"], "summary": "Refresh tenant session", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_refresh", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_refresh`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantRefreshRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantRefreshResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/tenant/auth/logout": {"post": {"tags": ["Tenant"], "summary": "Log out tenant", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_logout", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_logout`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantLogoutRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantLogoutResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/auth/password/forgot": {"post": {"tags": ["Tenant"], "summary": "Start tenant password recovery", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_forgot_password", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_forgot_password`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantForgotPasswordRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantPasswordResetStartResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/tenant/auth/password/reset": {"post": {"tags": ["Tenant"], "summary": "Reset tenant password", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_reset_password", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_reset_password`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantResetPasswordRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/tenant/me": {"get": {"tags": ["Tenant"], "summary": "Get tenant account", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_me", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantMeResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Tenant"], "summary": "Update tenant account", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_update_me", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_update_me`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantUpdateMeRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantMeResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/me/password": {"post": {"tags": ["Tenant"], "summary": "Change tenant password", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_change_password", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_change_password`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantChangePasswordRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/sessions": {"get": {"tags": ["Tenant"], "summary": "List tenant sessions", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_sessions", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantSessionListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/sessions/{session_id}": {"delete": {"tags": ["Tenant"], "summary": "Revoke tenant session", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_revoke_session", "parameters": [{"name": "session_id", "in": "path", "description": "Path parameter `session_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/account/export": {"post": {"tags": ["Tenant"], "summary": "Request tenant account export", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_account_export", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAccountExportResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/account": {"delete": {"tags": ["Tenant"], "summary": "Request tenant account deletion", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_delete_account", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAccountDeleteResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/renters/{renter_id}/tenant-invitations": {"post": {"tags": ["Tenant Access"], "summary": "Create tenant invitation", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_create_invitation", "parameters": [{"name": "renter_id", "in": "path", "description": "Path parameter `renter_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON request payload for `tenant_create_invitation`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateTenantInvitationRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantInvitationResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/invitations/{token}": {"get": {"tags": ["Tenant"], "summary": "Preview tenant invitation", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_preview_invitation", "parameters": [{"name": "token", "in": "path", "description": "Path parameter `token`.", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantInvitationPreviewResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": []}}, "/api/v1/tenant/invitations/{token}/accept": {"post": {"tags": ["Tenant"], "summary": "Accept tenant invitation", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_accept_invitation", "parameters": [{"name": "token", "in": "path", "description": "Path parameter `token`.", "required": true, "schema": {"type": "string"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantRenterLinkResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/claims": {"post": {"tags": ["Tenant"], "summary": "Create tenant renter claim", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_create_claim", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_create_claim`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantClaimRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantClaimResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/renter-links": {"get": {"tags": ["Tenant"], "summary": "List tenant renter links", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_renter_links", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantRenterLinkListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/renter-links/{link_id}": {"delete": {"tags": ["Tenant"], "summary": "Unlink tenant renter record", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_unlink_renter", "parameters": [{"name": "link_id", "in": "path", "description": "Path parameter `link_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/home": {"get": {"tags": ["Tenant"], "summary": "Get tenant home summary", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_home", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantHomeResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/profile": {"get": {"tags": ["Tenant"], "summary": "Get tenant profile", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_profile", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantProfileResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Tenant"], "summary": "Update tenant profile", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_update_profile", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_update_profile`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantUpdateProfileRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantProfileResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/household": {"get": {"tags": ["Tenant"], "summary": "Get tenant household", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_household", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantHouseholdResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Tenant"], "summary": "Update tenant household", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_update_household", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_update_household`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantUpdateHouseholdRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantHouseholdResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/residences": {"get": {"tags": ["Tenant"], "summary": "List tenant residences", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_residences", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantResidenceListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/residences/{residence_id}": {"get": {"tags": ["Tenant"], "summary": "Get tenant residence", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_residence_detail", "parameters": [{"name": "residence_id", "in": "path", "description": "Path parameter `residence_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantResidenceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/leases": {"get": {"tags": ["Tenant"], "summary": "List tenant leases", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_leases", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantLeaseListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/leases/current": {"get": {"tags": ["Tenant"], "summary": "Get current tenant lease", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_current_lease", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantLeaseResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/leases/{lease_id}": {"get": {"tags": ["Tenant"], "summary": "Get tenant lease", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_lease_detail", "parameters": [{"name": "lease_id", "in": "path", "description": "Path parameter `lease_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantLeaseResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/meter-readings": {"get": {"tags": ["Tenant"], "summary": "List tenant meter readings", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_meter_readings", "parameters": [{"name": "period", "in": "query", "description": "Optional tenant list filter `period` in YYYY-MM format.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantMeterReadingListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/meter-readings/{meter_reading_id}": {"get": {"tags": ["Tenant"], "summary": "Get tenant meter reading", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_meter_reading_detail", "parameters": [{"name": "meter_reading_id", "in": "path", "description": "Path parameter `meter_reading_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantMeterReadingResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/invoices": {"get": {"tags": ["Tenant"], "summary": "List tenant invoices", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_invoices", "parameters": [{"name": "period", "in": "query", "description": "Optional tenant list filter `period` in YYYY-MM format.", "required": false, "schema": {"type": "string", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}, {"name": "status", "in": "query", "description": "Optional tenant invoice status filter: ISSUED, PARTIALLY_PAID, PAID, OVERDUE, or CANCELLED.", "required": false, "schema": {"type": "string", "enum": ["ISSUED", "PARTIALLY_PAID", "PAID", "OVERDUE", "CANCELLED"]}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantInvoiceListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/invoices/{invoice_id}": {"get": {"tags": ["Tenant"], "summary": "Get tenant invoice", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_invoice_detail", "parameters": [{"name": "invoice_id", "in": "path", "description": "Path parameter `invoice_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantInvoiceDetailResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/invoices/{invoice_id}/payment-instructions": {"get": {"tags": ["Tenant"], "summary": "Get tenant payment instructions", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_payment_instructions", "parameters": [{"name": "invoice_id", "in": "path", "description": "Path parameter `invoice_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantPaymentInstructionResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/payments": {"get": {"tags": ["Tenant"], "summary": "List tenant payments", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_payments", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantPaymentListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/payments/{payment_id}": {"get": {"tags": ["Tenant"], "summary": "Get tenant payment", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_payment_detail", "parameters": [{"name": "payment_id", "in": "path", "description": "Path parameter `payment_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantPaymentResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/invoices/{invoice_id}/payment-confirmations": {"post": {"tags": ["Tenant"], "summary": "Create tenant payment confirmation", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_create_payment_confirmation", "parameters": [{"name": "invoice_id", "in": "path", "description": "Path parameter `invoice_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON request payload for `tenant_create_payment_confirmation`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/CreateTenantPaymentConfirmationRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantPaymentConfirmationResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/payment-confirmations": {"get": {"tags": ["Tenant"], "summary": "List tenant payment confirmations", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_payment_confirmations", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantPaymentConfirmationListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/payment-confirmations/{confirmation_id}": {"get": {"tags": ["Tenant"], "summary": "Get tenant payment confirmation", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_payment_confirmation_detail", "parameters": [{"name": "confirmation_id", "in": "path", "description": "Path parameter `confirmation_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantPaymentConfirmationResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/maintenance-tickets": {"get": {"tags": ["Tenant"], "summary": "List tenant maintenance tickets", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_maintenance_tickets", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantMaintenanceTicketListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Tenant"], "summary": "Create tenant maintenance ticket", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_create_maintenance_ticket", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_create_maintenance_ticket`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantCreateMaintenanceTicketRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantMaintenanceTicketResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/maintenance-tickets/{ticket_id}": {"get": {"tags": ["Tenant"], "summary": "Get tenant maintenance ticket", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_maintenance_ticket_detail", "parameters": [{"name": "ticket_id", "in": "path", "description": "Path parameter `ticket_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantMaintenanceTicketResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Tenant"], "summary": "Update tenant maintenance ticket", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_update_maintenance_ticket", "parameters": [{"name": "ticket_id", "in": "path", "description": "Path parameter `ticket_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON request payload for `tenant_update_maintenance_ticket`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantUpdateMaintenanceTicketRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantMaintenanceTicketResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/maintenance-tickets/{ticket_id}/comments": {"post": {"tags": ["Tenant"], "summary": "Create tenant ticket comment", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_create_ticket_comment", "parameters": [{"name": "ticket_id", "in": "path", "description": "Path parameter `ticket_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON request payload for `tenant_create_ticket_comment`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantCreateCommentRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantCommentResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/maintenance-tickets/{ticket_id}/attachments": {"post": {"tags": ["Tenant"], "summary": "Create tenant ticket attachment", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_create_ticket_attachment", "parameters": [{"name": "ticket_id", "in": "path", "description": "Path parameter `ticket_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON request payload for `tenant_create_ticket_attachment`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantCreateAttachmentRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAttachmentResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/maintenance-tickets/{ticket_id}/attachments/{attachment_id}": {"delete": {"tags": ["Tenant"], "summary": "Delete tenant ticket attachment", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_delete_ticket_attachment", "parameters": [{"name": "ticket_id", "in": "path", "description": "Path parameter `ticket_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "attachment_id", "in": "path", "description": "Path parameter `attachment_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/notifications": {"get": {"tags": ["Tenant"], "summary": "List tenant notifications", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_notifications", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantNotificationListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/notifications/{notification_id}/read": {"post": {"tags": ["Tenant"], "summary": "Mark tenant notification read", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_mark_notification_read", "parameters": [{"name": "notification_id", "in": "path", "description": "Path parameter `notification_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/notifications/read-all": {"post": {"tags": ["Tenant"], "summary": "Mark all tenant notifications read", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_mark_all_notifications_read", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/notification-preferences": {"get": {"tags": ["Tenant"], "summary": "Get tenant notification preferences", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_notification_preferences", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantNotificationPreferencesResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "patch": {"tags": ["Tenant"], "summary": "Update tenant notification preferences", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_update_notification_preferences", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_update_notification_preferences`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantUpdateNotificationPreferencesRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantNotificationPreferencesResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/devices": {"post": {"tags": ["Tenant"], "summary": "Register tenant device", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_register_device", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_register_device`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantRegisterDeviceRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantDeviceResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/devices/{device_id}": {"delete": {"tags": ["Tenant"], "summary": "Delete tenant device", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_delete_device", "parameters": [{"name": "device_id", "in": "path", "description": "Path parameter `device_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/activity": {"get": {"tags": ["Tenant"], "summary": "List tenant activity", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_activity", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantActivityListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/documents": {"get": {"tags": ["Tenant"], "summary": "List tenant documents", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_documents", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantDocumentListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/documents/{document_id}": {"get": {"tags": ["Tenant"], "summary": "Get tenant document", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_document_detail", "parameters": [{"name": "document_id", "in": "path", "description": "Path parameter `document_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantDocumentResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/documents/{document_id}/download": {"get": {"tags": ["Tenant"], "summary": "Download tenant document", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_document_download", "parameters": [{"name": "document_id", "in": "path", "description": "Path parameter `document_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantDocumentDownloadResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/messages/threads": {"get": {"tags": ["Tenant"], "summary": "List tenant message threads", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_threads", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantThreadListResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}, "post": {"tags": ["Tenant"], "summary": "Create tenant message thread", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_create_thread", "parameters": [], "requestBody": {"description": "JSON request payload for `tenant_create_thread`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantCreateThreadRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantThreadResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/messages/threads/{thread_id}": {"get": {"tags": ["Tenant"], "summary": "Get tenant message thread", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_thread_detail", "parameters": [{"name": "thread_id", "in": "path", "description": "Path parameter `thread_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantThreadResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/messages/threads/{thread_id}/messages": {"post": {"tags": ["Tenant"], "summary": "Create tenant thread message", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_create_thread_message", "parameters": [{"name": "thread_id", "in": "path", "description": "Path parameter `thread_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON request payload for `tenant_create_thread_message`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantCreateMessageRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantThreadMessageResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant/messages/threads/{thread_id}/attachments": {"post": {"tags": ["Tenant"], "summary": "Create tenant thread attachment", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_create_thread_attachment", "parameters": [{"name": "thread_id", "in": "path", "description": "Path parameter `thread_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "requestBody": {"description": "JSON request payload for `tenant_create_thread_attachment`.", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/TenantCreateAttachmentRequest"}}}, "required": true}, "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAttachmentResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/renters/{renter_id}/tenant-access": {"get": {"tags": ["Tenant Access"], "summary": "Get renter tenant access", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_access", "parameters": [{"name": "renter_id", "in": "path", "description": "Path parameter `renter_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAccessResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/renters/{renter_id}/tenant-access/suspend": {"post": {"tags": ["Tenant Access"], "summary": "Suspend renter tenant access", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_suspend_access", "parameters": [{"name": "renter_id", "in": "path", "description": "Path parameter `renter_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/renters/{renter_id}/tenant-access/restore": {"post": {"tags": ["Tenant Access"], "summary": "Restore renter tenant access", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_restore_access", "parameters": [{"name": "renter_id", "in": "path", "description": "Path parameter `renter_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/renters/{renter_id}/tenant-access/{tenant_user_id}": {"delete": {"tags": ["Tenant Access"], "summary": "Remove renter tenant access", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_remove_access", "parameters": [{"name": "renter_id", "in": "path", "description": "Path parameter `renter_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}, {"name": "tenant_user_id", "in": "path", "description": "Path parameter `tenant_user_id`.", "required": true, "schema": {"type": "string", "format": "uuid"}}], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAckResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}, "/api/v1/tenant-access/audit": {"get": {"tags": ["Tenant Access"], "summary": "List tenant access audit events", "description": "Implements a real Phase 5 tenant/renter API route with persisted data access and tenant/organization scoping.", "operationId": "tenant_access_audit", "parameters": [], "responses": {"200": {"description": "Tenant API operation succeeded", "content": {"application/json": {"schema": {"type": "object", "required": ["data", "request_id"], "properties": {"data": {"$ref": "#/components/schemas/TenantAccessAuditResponse", "description": "Endpoint-specific response payload. See the referenced schema for the resource fields."}, "request_id": {"type": "string", "description": "Request correlation identifier returned from `X-Request-Id` or generated by the API."}, "meta": {"type": "object", "description": "Optional response metadata such as pagination limits, counts, or export context."}}}}}}, "400": {"description": "Bad request or request validation failed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "401": {"description": "Authentication is required or invalid", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "403": {"description": "Permission denied", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "404": {"description": "Resource or route not found", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "405": {"description": "Method not allowed", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "409": {"description": "Resource conflict or invalid state transition", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "415": {"description": "Unsupported media type", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "429": {"description": "Rate limit exceeded", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}, "500": {"description": "Internal server error", "content": {"application/json": {"schema": {"$ref": "#/components/schemas/ErrorBody"}}}}}, "security": [{"bearerAuth": []}]}}}, "components": {"schemas": {"AccountActionCompleteRequest": {"type": "object", "description": "Request payload for account action complete.", "required": ["token"], "properties": {"token": {"type": "string", "description": "token value for account action complete request."}, "password": {"type": ["string", "null"], "description": "Plaintext password accepted only in authentication requests."}}}, "AccountActionCompleteResponse": {"type": "object", "description": "Response payload for account action complete.", "required": ["completed", "purpose"], "properties": {"completed": {"type": "boolean", "description": "completed value for account action complete response."}, "purpose": {"type": "string", "description": "purpose value for account action complete response."}}}, "AccountActionInspectRequest": {"type": "object", "description": "Request payload for account action inspect.", "required": ["token"], "properties": {"token": {"type": "string", "description": "token value for account action inspect request."}}}, "AccountActionInspectResponse": {"type": "object", "description": "Response payload for account action inspect.", "required": ["subject_type", "purpose", "expires_at"], "properties": {"subject_type": {"type": "string", "description": "subject type value for account action inspect response."}, "purpose": {"type": "string", "description": "purpose value for account action inspect response."}, "display_name": {"type": ["string", "null"], "description": "Human-readable display name."}, "expires_at": {"type": "string", "format": "date-time", "description": "expires at value for account action inspect response."}}}, "AccountingAllocationPreviewQuery": {"type": "object", "description": "Schema for accounting allocation preview query.", "required": ["date_from", "date_to"], "properties": {"date_from": {"type": "string", "description": "date from value for accounting allocation preview query."}, "date_to": {"type": "string", "description": "date to value for accounting allocation preview query."}, "allocation_method": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/ExpenseAllocationMethod"}], "description": "allocation method value for accounting allocation preview query."}}}, "AccountingDateRangeQuery": {"type": "object", "description": "Schema for accounting date range query.", "required": ["date_from", "date_to"], "properties": {"date_from": {"type": "string", "description": "date from value for accounting date range query."}, "date_to": {"type": "string", "description": "date to value for accounting date range query."}}}, "AddMemberRequest": {"type": "object", "description": "Request payload for add member.", "required": ["identifier", "role"], "properties": {"identifier": {"type": "string", "description": "Human-readable identifier or code for the resource.", "minLength": 1}, "role": {"$ref": "#/components/schemas/OrganizationRole", "description": "Role granted to the user in the relevant scope."}}}, "AddMembershipRequest": {"type": "object", "description": "Request payload for add membership.", "required": ["user_id", "role", "reason", "action_token"], "properties": {"user_id": {"type": "string", "format": "uuid", "description": "UUID identifier for user."}, "role": {"type": "string", "description": "Role granted to the user in the relevant scope."}, "reason": {"type": "string", "description": "Operator-provided reason for a lifecycle action."}, "action_token": {"type": "string", "description": "action token value for add membership request."}}}, "AdminListingResponse": {"type": "object", "description": "Admin view of a listing (includes publish state + slug).", "required": ["id", "organization_id", "property_id", "room_id", "slug", "headline", "amenities", "is_published", "images", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "slug": {"type": "string", "description": "URL-safe slug for the resource."}, "headline": {"type": "string", "description": "headline value for admin listing response."}, "description": {"type": ["string", "null"], "description": "Human-readable description for the resource or line item."}, "amenities": {"type": "array", "items": {"type": "string"}, "description": "amenities value for admin listing response."}, "contact_phone": {"type": ["string", "null"], "description": "contact phone value for admin listing response."}, "zalo_url": {"type": ["string", "null"], "description": "zalo url value for admin listing response."}, "available_date": {"type": ["string", "null"], "format": "date", "description": "available date value for admin listing response."}, "min_lease_months": {"type": ["integer", "null"], "format": "int32", "description": "min lease months value for admin listing response."}, "is_published": {"type": "boolean", "description": "is published value for admin listing response."}, "images": {"type": "array", "items": {"$ref": "#/components/schemas/ListingImageResponse"}, "description": "images value for admin listing response."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "AdminLoginRequest": {"type": "object", "description": "Request payload for admin login.", "required": ["identifier", "password"], "properties": {"identifier": {"type": "string", "description": "Human-readable identifier or code for the resource."}, "password": {"type": "string", "description": "Plaintext password accepted only in authentication requests."}}}, "AdminLoginResponse": {"type": "object", "description": "Response payload for admin login.", "required": ["mfa_required"], "properties": {"mfa_required": {"type": "boolean", "description": "mfa required value for admin login response."}, "challenge_token": {"type": ["string", "null"], "description": "challenge token value for admin login response."}, "session": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/AdminSessionResponse"}], "description": "session value for admin login response."}}}, "AdminMfaVerifyRequest": {"type": "object", "description": "Request payload for admin mfa verify.", "required": ["challenge_token", "code"], "properties": {"challenge_token": {"type": "string", "description": "challenge token value for admin mfa verify request."}, "code": {"type": "string", "description": "Stable machine-readable code for the value."}}}, "AdminSessionResponse": {"type": "object", "description": "Response payload for admin session.", "required": ["access_token", "expires_in", "user"], "properties": {"access_token": {"type": "string", "description": "Short-lived bearer token used in the Authorization header."}, "expires_in": {"type": "integer", "format": "int64", "description": "expires in value for admin session response."}, "user": {"$ref": "#/components/schemas/PlatformUserResponse", "description": "User profile returned by the response."}}}, "AdminUnit": {"type": "object", "description": "One administrative unit, localized to the negotiated request locale.", "required": ["code", "level", "name"], "properties": {"code": {"type": "string", "description": "Stable official code (province = 2 digits, ward = 5 digits)."}, "level": {"type": "string", "description": "`province` or `ward`."}, "parent_code": {"type": ["string", "null"], "description": "Province code for a ward; `null` for a province."}, "name": {"type": "string", "description": "Localized name (vi/en by `Accept-Language`)."}, "lat": {"type": ["number", "null"], "format": "double", "description": "lat value for admin unit."}, "lng": {"type": ["number", "null"], "format": "double", "description": "lng value for admin unit."}, "distance_km": {"type": ["number", "null"], "format": "double", "description": "Great-circle distance in km from the query `lat`/`lng`, when supplied."}}}, "AdminUnitListResponse": {"type": "object", "description": "List response payload containing admin unit.", "required": ["units"], "properties": {"units": {"type": "array", "items": {"$ref": "#/components/schemas/AdminUnit"}, "description": "units value for admin unit list response."}}}, "AmenityOption": {"type": "object", "description": "An amenity dropdown option derived from publicly-visible listings.", "required": ["value", "label", "listing_count"], "properties": {"value": {"type": "string", "description": "Stable raw amenity value (e.g. `wifi`)."}, "label": {"type": "string", "description": "Localized label (falls back to the raw value when uncatalogued)."}, "listing_count": {"type": "integer", "format": "int64", "description": "listing count value for amenity option."}}}, "AuthResponse": {"type": "object", "description": "Response payload for auth.", "required": ["access_token", "refresh_token", "user", "organization"], "properties": {"access_token": {"type": "string", "description": "Short-lived bearer token used in the Authorization header."}, "refresh_token": {"type": "string", "description": "Longer-lived token used only to refresh or revoke sessions."}, "user": {"$ref": "#/components/schemas/UserInfo", "description": "User profile returned by the response."}, "organization": {"$ref": "#/components/schemas/OrganizationInfo", "description": "Organization record included in the response."}}}, "BankHubLinkTokenResponse": {"type": "object", "description": "Response payload for bank hub link token.", "required": ["hosted_link_url", "expires_at", "completion_redirect_url"], "properties": {"hosted_link_url": {"type": "string", "description": "hosted link url value for bank hub link token response."}, "expires_at": {"type": "string", "description": "expires at value for bank hub link token response."}, "completion_redirect_url": {"type": "string", "description": "completion redirect url value for bank hub link token response."}}}, "BankHubLinkedAccountResponse": {"type": "object", "description": "Response payload for bank hub linked account.", "required": ["sepay_bank_account_xid", "account_number", "connection_status", "is_default"], "properties": {"id": {"type": ["string", "null"], "format": "uuid", "description": "Stable UUID identifier for this resource."}, "sepay_bank_account_xid": {"type": "string", "description": "sepay bank account xid value for bank hub linked account response."}, "bank_name": {"type": ["string", "null"], "description": "Bank name for the payment account."}, "account_holder_name": {"type": ["string", "null"], "description": "account holder name value for bank hub linked account response."}, "account_number": {"type": "string", "description": "account number value for bank hub linked account response."}, "connection_status": {"type": "string", "description": "connection status value for bank hub linked account response."}, "last_synced_at": {"type": ["string", "null"], "format": "date-time", "description": "last synced at value for bank hub linked account response."}, "property_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for property."}, "is_default": {"type": "boolean", "description": "Whether this account or setting is the default choice."}}}, "BankHubStatusResponse": {"type": "object", "description": "Response payload for bank hub status.", "required": ["enabled", "linked_accounts"], "properties": {"enabled": {"type": "boolean", "description": "enabled value for bank hub status response."}, "company_xid": {"type": ["string", "null"], "description": "company xid value for bank hub status response."}, "company_status": {"type": ["string", "null"], "description": "company status value for bank hub status response."}, "linked_accounts": {"type": "array", "items": {"$ref": "#/components/schemas/BankHubLinkedAccountResponse"}, "description": "linked accounts value for bank hub status response."}}}, "BillingSettingsResponse": {"type": "object", "description": "Response payload for billing settings.", "required": ["id", "organization_id", "property_id", "billing_day", "due_day", "electricity_pricing_type", "electricity_unit_price", "electricity_fixed_amount", "water_pricing_type", "water_unit_price", "water_fixed_amount", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "billing_day": {"type": "integer", "format": "int32", "description": "Day of month used as the default billing day."}, "due_day": {"type": "integer", "format": "int32", "description": "Day of month used to calculate invoice due dates."}, "electricity_pricing_type": {"$ref": "#/components/schemas/PricingType", "description": "Pricing mode used for electricity charges."}, "electricity_unit_price": {"type": "string", "description": "Unit price applied to electricity usage.", "example": "3500"}, "electricity_fixed_amount": {"type": "string", "description": "Fixed electricity charge applied during invoice generation.", "example": "0"}, "water_pricing_type": {"$ref": "#/components/schemas/PricingType", "description": "Pricing mode used for water charges."}, "water_unit_price": {"type": "string", "description": "Unit price applied to water usage.", "example": "15000"}, "water_fixed_amount": {"type": "string", "description": "Fixed water charge applied during invoice generation.", "example": "0"}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "BulkCreateRoomsRequest": {"type": "object", "description": "Request payload for bulk create rooms.", "required": ["count"], "properties": {"count": {"type": "integer", "format": "int32", "description": "Number of rows represented by the response metadata.", "example": 10, "maximum": 50, "minimum": 1}, "name_prefix": {"type": ["string", "null"], "description": "name prefix value for bulk create rooms request.", "example": "Ph\u00f2ng", "maxLength": 80}, "start_number": {"type": ["integer", "null"], "format": "int32", "description": "start number value for bulk create rooms request.", "example": 1, "maximum": 9999, "minimum": 1}, "floor": {"type": ["string", "null"], "description": "Floor label or number where the room is located.", "maxLength": 80}, "base_rent": {"type": ["string", "null"], "description": "Default monthly rent amount for the room.", "example": "3000000"}, "default_deposit": {"type": ["string", "null"], "description": "Default deposit amount used when creating leases.", "example": "3000000"}, "area_m2": {"type": ["number", "null"], "format": "double", "description": "Room area in square meters.", "minimum": 0}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "BulkCreateRoomsResponse": {"type": "object", "description": "Response payload for bulk create rooms.", "required": ["property_id", "created_count", "rooms"], "properties": {"property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "created_count": {"type": "integer", "description": "created count value for bulk create rooms response.", "minimum": 0}, "rooms": {"type": "array", "items": {"$ref": "#/components/schemas/RoomResponse"}, "description": "Rooms returned by the response."}}}, "BulkInvoiceGenerationResponse": {"type": "object", "description": "Response payload for bulk invoice generation.", "required": ["property_id", "period", "generated_count", "invoices", "skipped_count", "skipped"], "properties": {"property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "period": {"type": "string", "description": "Billing period in YYYY-MM format."}, "generated_count": {"type": "integer", "description": "Number of invoices generated by the bulk operation.", "minimum": 0}, "invoices": {"type": "array", "items": {"$ref": "#/components/schemas/InvoiceResponse"}, "description": "Invoices returned by the response."}, "skipped_count": {"type": "integer", "description": "Number of rooms skipped because an invoice already existed for the period.", "minimum": 0}, "skipped": {"type": "array", "items": {"$ref": "#/components/schemas/SkippedRoom"}, "description": "Rooms skipped by bulk generation because a non-cancelled invoice already existed for the period."}}}, "BulkUpsertMeterReadingsRequest": {"type": "object", "description": "Request payload for bulk upsert meter readings.", "required": ["period", "readings"], "properties": {"period": {"type": "string", "description": "Billing period in YYYY-MM format.", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}, "readings": {"type": "array", "items": {"$ref": "#/components/schemas/RoomMeterReading"}, "description": "Meter reading rows submitted in a bulk upsert request.", "minItems": 1}}}, "BulkUpsertMeterReadingsResponse": {"type": "object", "description": "Response payload for bulk upsert meter readings.", "required": ["upserted_count", "meter_readings"], "properties": {"upserted_count": {"type": "integer", "description": "Number of rows created or updated by the upsert operation.", "minimum": 0}, "meter_readings": {"type": "array", "items": {"$ref": "#/components/schemas/MeterReadingResponse"}, "description": "Meter readings returned by the response."}}}, "CancelInvoiceRequest": {"type": "object", "description": "Request payload for cancel invoice.", "properties": {"reason": {"type": ["string", "null"], "description": "Operator-provided reason for a lifecycle action.", "maxLength": 500}}}, "CancelLeaseRequest": {"type": "object", "description": "Request payload for cancel lease.", "properties": {"note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "ChangePasswordRequest": {"type": "object", "description": "Request payload for change password.", "required": ["current_password", "new_password"], "properties": {"current_password": {"type": "string", "description": "current password value for change password request.", "maxLength": 1024, "minLength": 1}, "new_password": {"type": "string", "description": "new password value for change password request.", "maxLength": 1024, "minLength": 8}, "refresh_token": {"type": ["string", "null"], "description": "Optional current refresh token. When supplied, the password-change\nflow preserves this session and revokes the user's other refresh\nsessions. When omitted, all refresh sessions are revoked.", "maxLength": 512, "minLength": 1}}}, "ChangePlatformPasswordRequest": {"type": "object", "description": "Request payload for change platform password.", "required": ["new_password", "action_token"], "properties": {"new_password": {"type": "string", "description": "new password value for change platform password request."}, "action_token": {"type": "string", "description": "action token value for change platform password request."}}}, "CommandAckResponse": {"type": "object", "description": "Response payload for command ack.", "required": ["ok"], "properties": {"ok": {"type": "boolean", "description": "ok value for command ack response."}}}, "CompleteOAuthSignupRequest": {"type": "object", "description": "Request payload for complete o auth signup.", "required": ["signup_token", "username", "organization_name"], "properties": {"signup_token": {"type": "string", "description": "signup token value for complete o auth signup request.", "maxLength": 160, "minLength": 1}, "username": {"type": "string", "description": "Unique username used for login and display.", "maxLength": 50, "minLength": 3}, "organization_name": {"type": "string", "description": "Human-readable organization name.", "maxLength": 100, "minLength": 2}, "display_name": {"type": ["string", "null"], "description": "Human-readable display name.", "maxLength": 100}}}, "ConfirmMfaRequest": {"type": "object", "description": "Request payload for confirm mfa.", "required": ["code"], "properties": {"code": {"type": "string", "description": "Stable machine-readable code for the value."}}}, "CreateFeeTemplateRequest": {"type": "object", "description": "Request payload for create fee template.", "required": ["name", "fee_type", "amount"], "properties": {"name": {"type": "string", "description": "Human-readable name for the resource.", "maxLength": 120, "minLength": 1}, "fee_type": {"$ref": "#/components/schemas/FeeType", "description": "Classification of the recurring fee."}, "amount": {"type": "string", "description": "2-dp decimal string; validated >= 0 in the service.", "example": "150000"}, "is_default": {"type": ["boolean", "null"], "description": "Whether this account or setting is the default choice."}}}, "CreateInvoiceLineRequest": {"type": "object", "description": "Request payload for create invoice line.", "required": ["line_type", "description", "quantity", "unit_price"], "properties": {"line_type": {"$ref": "#/components/schemas/LineType", "description": "Invoice line classification used for totals."}, "description": {"type": "string", "description": "Human-readable description for the resource or line item.", "maxLength": 255, "minLength": 1}, "quantity": {"type": "string", "description": "2-dp decimal string; validated >= 0 in the service.", "example": "1"}, "unit_price": {"type": "string", "description": "Unit price used for invoice line calculations.", "example": "1500000"}, "metadata": {"description": "Additional structured metadata attached to the record."}}}, "CreateLandlordRequest": {"type": "object", "description": "Request payload for create landlord.", "required": ["username", "display_name", "organization_name", "plan_code", "reason", "action_token"], "properties": {"username": {"type": "string", "description": "Unique username used for login and display."}, "email": {"type": ["string", "null"], "description": "Email address associated with the user or renter."}, "display_name": {"type": "string", "description": "Human-readable display name."}, "organization_name": {"type": "string", "description": "Human-readable organization name."}, "plan_code": {"type": "string", "description": "Commercial plan code assigned to an organization."}, "reason": {"type": "string", "description": "Operator-provided reason for a lifecycle action."}, "action_token": {"type": "string", "description": "action token value for create landlord request."}}}, "CreateListingInquiryRequest": {"type": "object", "description": "Public inquiry submission body.", "required": ["renter_name", "phone", "message"], "properties": {"renter_name": {"type": "string", "description": "Human-readable renter name.", "maxLength": 160, "minLength": 1}, "phone": {"type": "string", "description": "Phone number associated with the renter or user.", "maxLength": 40, "minLength": 6}, "email": {"type": ["string", "null"], "format": "email", "description": "Email address associated with the user or renter."}, "message": {"type": "string", "description": "Human-readable message safe to show in client logs or UI.", "maxLength": 2000, "minLength": 1}}}, "CreateMaintenanceTicketRequest": {"type": "object", "description": "Request payload for create maintenance ticket.", "required": ["property_id", "title", "description"], "properties": {"property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "room_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for room."}, "renter_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for renter."}, "invoice_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for invoice."}, "title": {"type": "string", "description": "title value for create maintenance ticket request.", "maxLength": 160, "minLength": 1}, "description": {"type": "string", "description": "Human-readable description for the resource or line item.", "maxLength": 2000, "minLength": 1}, "priority": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/MaintenanceTicketPriority"}], "description": "priority value for create maintenance ticket request."}, "reported_by_name": {"type": ["string", "null"], "description": "reported by name value for create maintenance ticket request.", "maxLength": 160}, "reported_by_contact": {"type": ["string", "null"], "description": "reported by contact value for create maintenance ticket request.", "maxLength": 160}}}, "CreateOrganizationRequest": {"type": "object", "description": "Request payload for create organization.", "required": ["name"], "properties": {"name": {"type": "string", "description": "Human-readable name for the resource.", "maxLength": 100, "minLength": 2}, "slug": {"type": ["string", "null"], "description": "URL-safe slug for the resource.", "maxLength": 80}}}, "CreatePaymentAccountRequest": {"type": "object", "description": "Request payload for create payment account.", "properties": {"property_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for property."}, "bank_name": {"type": ["string", "null"], "description": "Bank name for the payment account.", "maxLength": 120}, "sepay_bank_code": {"type": ["string", "null"], "description": "sepay bank code value for create payment account request.", "maxLength": 32}, "bank_code": {"type": ["string", "null"], "description": "bank code value for create payment account request."}, "bank_account_number": {"type": ["string", "null"], "description": "Bank account number used for tenant transfers.", "maxLength": 80}, "bank_account_holder": {"type": ["string", "null"], "description": "Name of the bank account holder for transfers.", "maxLength": 120}, "is_default": {"type": ["boolean", "null"], "description": "Whether this account or setting is the default choice."}}}, "CreatePlatformUserRequest": {"type": "object", "description": "Request payload for create platform user.", "required": ["username", "display_name", "role", "reason", "action_token"], "properties": {"username": {"type": "string", "description": "Unique username used for login and display."}, "email": {"type": ["string", "null"], "description": "Email address associated with the user or renter."}, "display_name": {"type": "string", "description": "Human-readable display name."}, "role": {"type": "string", "description": "Role granted to the user in the relevant scope."}, "reason": {"type": "string", "description": "Operator-provided reason for a lifecycle action."}, "action_token": {"type": "string", "description": "action token value for create platform user request."}}}, "CreatePropertyRequest": {"type": "object", "description": "Request payload for create property.", "required": ["name"], "properties": {"name": {"type": "string", "description": "Human-readable name for the resource.", "maxLength": 120, "minLength": 1}, "address": {"type": ["string", "null"], "description": "Street address or address detail for the resource.", "maxLength": 255}, "city": {"type": ["string", "null"], "description": "City portion of the address.", "maxLength": 80}, "district": {"type": ["string", "null"], "description": "District portion of the address.", "maxLength": 80}, "ward": {"type": ["string", "null"], "description": "Ward portion of the address.", "maxLength": 80}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "CreateRenterRequest": {"type": "object", "description": "Request payload for create renter.", "required": ["full_name", "phone"], "properties": {"full_name": {"type": "string", "description": "Full legal or display name for the person.", "maxLength": 160, "minLength": 1}, "phone": {"type": "string", "description": "Required Vietnam mobile number for renter creation, accepted as 0912345678 or +84912345678.", "example": "0912345678", "maxLength": 40, "minLength": 1, "pattern": "^(0[35789][0-9]{8}|\\+84[35789][0-9]{8})$"}, "email": {"type": ["string", "null"], "format": "email", "description": "Email address associated with the user or renter."}, "identity_number": {"type": ["string", "null"], "description": "Government or landlord-recorded identity number for the renter.", "maxLength": 80}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "CreateRoomRequest": {"type": "object", "description": "Request payload for create room.", "required": ["name"], "properties": {"name": {"type": "string", "description": "Human-readable name for the resource.", "maxLength": 120, "minLength": 1}, "floor": {"type": ["string", "null"], "description": "Floor label or number where the room is located.", "maxLength": 80}, "base_rent": {"type": ["string", "null"], "description": "Default monthly rent amount for the room.", "example": "3000000"}, "default_deposit": {"type": ["string", "null"], "description": "Default deposit amount used when creating leases.", "example": "3000000"}, "area_m2": {"type": ["number", "null"], "format": "double", "description": "Room area in square meters.", "minimum": 0}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "CreateTenantInvitationRequest": {"type": "object", "description": "Request payload for create tenant invitation.", "properties": {"email": {"type": ["string", "null"], "format": "email", "description": "Email address associated with the user or renter.", "maxLength": 254}, "phone": {"type": ["string", "null"], "description": "Phone number associated with the renter or user.", "maxLength": 40}, "expires_in_days": {"type": ["integer", "null"], "format": "int64", "description": "expires in days value for create tenant invitation request.", "maximum": 30, "minimum": 1}}}, "CreateTenantPaymentConfirmationRequest": {"type": "object", "description": "Request payload for create tenant payment confirmation.", "required": ["amount"], "properties": {"amount": {"type": "string", "description": "Money amount represented in the API currency unit.", "example": "1250000", "maxLength": 32, "minLength": 1}, "paid_at": {"type": ["string", "null"], "format": "date-time", "description": "paid at value for create tenant payment confirmation request."}, "transfer_reference": {"type": ["string", "null"], "description": "transfer reference value for create tenant payment confirmation request.", "maxLength": 160}, "receipt_url": {"type": ["string", "null"], "description": "receipt url value for create tenant payment confirmation request.", "maxLength": 500}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "CurrentOrganizationResponse": {"type": "object", "description": "Response payload for current organization.", "required": ["organization"], "properties": {"organization": {"$ref": "#/components/schemas/OrganizationInfo", "description": "Organization record included in the response."}}}, "CursorMeta": {"type": "object", "description": "Schema for cursor meta.", "required": ["limit"], "properties": {"limit": {"type": "integer", "format": "int64", "description": "Maximum number of rows requested or returned."}, "next_cursor": {"type": ["string", "null"], "description": "next cursor value for cursor meta."}}}, "CursorQuery": {"type": "object", "description": "Schema for cursor query.", "properties": {"cursor": {"type": ["string", "null"], "description": "cursor value for cursor query."}, "limit": {"type": ["integer", "null"], "format": "int64", "description": "Maximum number of rows requested or returned."}, "q": {"type": ["string", "null"], "description": "q value for cursor query."}, "status": {"type": ["string", "null"], "description": "Current lifecycle or operational status."}, "plan_code": {"type": ["string", "null"], "description": "Commercial plan code assigned to an organization."}, "role": {"type": ["string", "null"], "description": "Role granted to the user in the relevant scope."}, "action": {"type": ["string", "null"], "description": "Audit or workflow action name."}, "resource_type": {"type": ["string", "null"], "description": "resource type value for cursor query."}}}, "DashboardQuery": {"type": "object", "description": "Schema for dashboard query.", "properties": {"range": {"type": ["string", "null"], "description": "range value for dashboard query."}}}, "DashboardSummaryResponse": {"type": "object", "description": "Response payload for dashboard summary.", "required": ["period_from", "period_to", "total_receivable", "paid_amount", "unpaid_amount", "overdue_amount", "invoice_count", "paid_invoice_count", "overdue_invoice_count", "total_rooms", "occupied_rooms", "vacant_rooms", "maintenance_rooms", "hidden_rooms", "occupancy_rate", "overdue_invoices"], "properties": {"period": {"type": ["string", "null"], "description": "Billing period in YYYY-MM format."}, "period_from": {"type": "string", "description": "period from value for dashboard summary response."}, "period_to": {"type": "string", "description": "period to value for dashboard summary response."}, "property_id": {"type": ["string", "null"], "format": "uuid", "description": "Property scope echoed back; `null` when the summary is organization-wide."}, "total_receivable": {"type": "string", "description": "Total receivable amount for the period."}, "paid_amount": {"type": "string", "description": "Amount already paid toward the invoice or period total."}, "unpaid_amount": {"type": "string", "description": "Amount still unpaid for the invoice or report row."}, "overdue_amount": {"type": "string", "description": "Total amount overdue for the period."}, "invoice_count": {"type": "integer", "format": "int64", "description": "Number of invoices included in the calculation."}, "paid_invoice_count": {"type": "integer", "format": "int64", "description": "Number of invoices fully paid."}, "overdue_invoice_count": {"type": "integer", "format": "int64", "description": "Number of invoices currently overdue."}, "total_rooms": {"type": "integer", "format": "int64", "description": "Total number of rooms in scope."}, "occupied_rooms": {"type": "integer", "format": "int64", "description": "Number of occupied rooms."}, "vacant_rooms": {"type": "integer", "format": "int64", "description": "Number of rooms currently vacant."}, "maintenance_rooms": {"type": "integer", "format": "int64", "description": "Rooms currently marked for maintenance."}, "hidden_rooms": {"type": "integer", "format": "int64", "description": "Rooms excluded from active availability views."}, "occupancy_rate": {"type": "number", "format": "double", "description": "Occupied room ratio represented as a decimal value."}, "overdue_invoices": {"type": "array", "items": {"$ref": "#/components/schemas/OverdueInvoiceSummary"}, "description": "Overdue invoice summaries returned by the response."}}}, "DisableMfaRequest": {"type": "object", "description": "Request payload for disable mfa.", "required": ["action_token"], "properties": {"action_token": {"type": "string", "description": "action token value for disable mfa request."}}}, "DisplayLabel": {"type": "object", "description": "A stable machine `value` paired with its localized human `label`. Additive\non the wire: clients that ignore it keep reading the raw enum field.", "required": ["value", "label"], "properties": {"value": {"type": "string", "description": "The stable enum wire value (unchanged across locales), e.g.\n`PARTIALLY_PAID`, `bank_transfer`, `electricity`.", "example": "PARTIALLY_PAID"}, "label": {"type": "string", "description": "The localized label for the negotiated request locale, e.g.\n`Thanh to\u00e1n m\u1ed9t ph\u1ea7n` (vi) or `Partially paid` (en).", "example": "Thanh to\u00e1n m\u1ed9t ph\u1ea7n"}}}, "EndLeaseRequest": {"type": "object", "description": "Request payload for end lease.", "required": ["end_date"], "properties": {"end_date": {"type": "string", "format": "date", "description": "Lease or report end date."}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "ErrorBody": {"type": "object", "description": "Standard error envelope returned by failed JSON requests.", "required": ["error"], "properties": {"error": {"$ref": "#/components/schemas/ErrorDetail", "description": "Error payload returned by a failed request."}}}, "ErrorDetail": {"type": "object", "description": "Machine-readable error detail with request correlation and optional field errors.", "required": ["code", "message"], "properties": {"code": {"type": "string", "description": "Stable machine-readable error code. Clients should branch on this value instead of parsing message.", "enum": ["bad_request", "bank_list_unavailable", "claim_invalid_organization", "conflict", "database_error", "duplicate_renter", "duplicate_renter_candidates", "email_already_exists", "empty_meter_readings", "forbidden", "internal_error", "invalid_body", "invalid_content_type", "invalid_credentials", "invalid_date_range", "invalid_fee_amount", "invalid_invoice_line", "invalid_json", "invalid_lease_dates", "invalid_listing_filter", "invalid_listing_image", "invalid_listing_inquiry", "invalid_location_query", "invalid_membership_status", "invalid_meter_reading", "invalid_organization_header", "invalid_organization_status", "invalid_import_csv", "invalid_maintenance_ticket", "invalid_path", "invalid_payment_amount", "invalid_payment_reference", "invalid_payment_reconciliation_mode", "invalid_period", "invalid_period_range", "invalid_query", "invalid_room_bulk_create", "accounting_audit_export_range_too_large", "accounting_audit_export_too_large", "accounting_document_number_conflict", "accounting_policy_currency_immutable", "accounting_policy_fiscal_year_invalid", "accounting_policy_locked_by_journal_entries", "accounting_policy_tax_rate_invalid", "accounting_journal_actor_invalid", "accounting_journal_already_approved", "accounting_journal_already_reversed", "accounting_journal_not_approved", "accounting_journal_not_approvable", "accounting_journal_not_found", "accounting_journal_reversal_conflict", "accounting_journal_reversal_source_not_allowed", "income_tax_accrual_conflict", "income_tax_accrual_date_out_of_period", "income_tax_amount_invalid", "income_tax_amount_mismatch", "income_tax_kind_not_allowed", "income_tax_rate_required", "income_tax_regime_required", "invoice_already_generated", "invoice_has_payments", "invoice_issue_date_before_lease_start", "invoice_issue_date_requires_issue", "invoice_line_not_editable", "invoice_total_negative", "invoice_not_cancelable", "invoice_not_editable", "invoice_not_issuable", "invoice_not_markable_overdue", "invoice_not_payable", "invoice_not_recreatable", "invoice_number_conflict", "invoice_update_empty", "last_owner_member", "lease_not_active", "member_already_exists", "meter_reading_already_exists", "meter_reading_decreases", "meter_reading_locked_by_invoice", "meter_reading_update_empty", "method_not_allowed", "invalid_media_upload", "media_storage_disabled", "media_storage_error", "media_storage_timeout", "maintenance_ticket_update_empty", "media_asset_not_attachable", "no_active_organization", "not_found", "organization_slug_already_exists", "organization_suspended", "oauth_handoff_conflict", "oauth_handoff_invalid", "oauth_identity_exists", "oauth_provider_already_linked", "oauth_provider_error", "oauth_provider_not_configured", "oauth_provider_unsupported", "oauth_state_conflict", "oauth_state_invalid", "oauth_signup_invalid", "payment_already_reversed", "payment_account_incomplete", "payment_account_bank_code_required", "payment_account_field_required", "payment_account_linked", "payment_account_linked_identity_locked", "payment_exceeds_invoice_balance", "payment_not_editable", "password_not_available", "payment_reconciliation_duplicate_reference", "payment_reconciliation_disabled", "payment_reconciliation_risk_ack_required", "payment_update_empty", "permission_denied", "review_item_not_actionable", "review_note_required", "sepay_bank_hub_account_not_linked", "sepay_bank_hub_account_ambiguous", "sepay_bank_hub_account_already_linked", "sepay_bank_hub_account_identity_mismatch", "sepay_bank_hub_account_inactive", "sepay_bank_hub_account_state_stale", "sepay_bank_hub_not_linked", "sepay_bank_hub_provisioning_conflict", "sepay_bank_hub_rejected", "sepay_bank_hub_unavailable", "push_provider_unavailable", "refresh_token_conflict", "room_has_active_lease", "room_name_already_exists", "room_not_in_property", "room_occupancy_not_settable", "super_admin_required", "too_many_requests", "unauthorized", "unsupported_electricity_pricing", "username_already_exists", "validation_failed"], "examples": ["validation_failed", "invalid_period", "invoice_already_generated", "payment_already_reversed", "organization_suspended"]}, "message": {"type": "string", "description": "Human-readable message safe to show in client logs or UI."}, "request_id": {"type": ["string", "null"], "description": "Request correlation identifier for tracing and support."}, "fields": {"type": "array", "items": {"$ref": "#/components/schemas/ErrorField"}, "description": "Field-level validation errors."}, "details": {"description": "Additional machine-readable details for the error or audit record."}}}, "ErrorField": {"type": "object", "description": "Validation error detail for one request field.", "required": ["path", "code", "message"], "properties": {"path": {"type": "string", "description": "Request field path that failed validation."}, "code": {"type": "string", "description": "Stable machine-readable code for the value."}, "message": {"type": "string", "description": "Human-readable message safe to show in client logs or UI."}}}, "ExpenseAllocationMethod": {"type": "string", "description": "Schema for expense allocation method.", "enum": ["revenue_share", "equal_room"]}, "FeeTemplateListResponse": {"type": "object", "description": "List response payload containing fee template.", "required": ["fee_templates"], "properties": {"fee_templates": {"type": "array", "items": {"$ref": "#/components/schemas/FeeTemplateResponse"}, "description": "Recurring fee templates included in the response."}}}, "FeeTemplateResponse": {"type": "object", "description": "Response payload for fee template.", "required": ["id", "organization_id", "property_id", "name", "fee_type", "amount", "is_default", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "name": {"type": "string", "description": "Human-readable name for the resource."}, "fee_type": {"$ref": "#/components/schemas/FeeType", "description": "Classification of the recurring fee."}, "amount": {"type": "string", "description": "Money amount represented in the API currency unit.", "example": "150000"}, "is_default": {"type": "boolean", "description": "Whether this account or setting is the default choice."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "FeeType": {"type": "string", "description": "Recurring fee classification used during invoice generation.", "enum": ["wifi", "garbage", "parking", "service", "laundry", "other"]}, "FilterOption": {"type": "object", "description": "A location dropdown option derived from publicly-visible listings.", "required": ["code", "name", "listing_count"], "properties": {"code": {"type": "string", "description": "Stable official administrative-unit code."}, "name": {"type": "string", "description": "Localized label."}, "listing_count": {"type": "integer", "format": "int64", "description": "listing count value for filter option."}}}, "GenerateAccountLinkRequest": {"type": "object", "description": "Request payload for generate account link.", "required": ["purpose", "reason", "action_token"], "properties": {"purpose": {"type": "string", "description": "purpose value for generate account link request."}, "reason": {"type": "string", "description": "Operator-provided reason for a lifecycle action."}, "action_token": {"type": "string", "description": "action token value for generate account link request."}}}, "GenerateBulkInvoicesRequest": {"type": "object", "description": "Request payload for generate bulk invoices.", "required": ["property_id", "period"], "properties": {"property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "period": {"type": "string", "description": "Billing period in YYYY-MM format.", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}}, "GenerateInvoiceRequest": {"type": "object", "description": "Request payload for generate invoice.", "required": ["room_id", "period"], "properties": {"room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "period": {"type": "string", "description": "Billing period in YYYY-MM format.", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}, "issue": {"type": ["boolean", "null"], "description": "When true, generate and issue the invoice in one operation. When false or omitted, the invoice remains DRAFT and issue_date must be omitted."}, "issue_date": {"type": ["string", "null"], "format": "date", "description": "Optional operational issue date used only when issue is true. If omitted while issuing, the date defaults from billing_settings.billing_day for the billing period."}, "due_date": {"type": ["string", "null"], "format": "date", "description": "Optional payment due date for a newly generated invoice. It may be earlier than the lease start date for advance payments, reservations, or deposits. This is not the invoice issue date, legal tax invoice date, or revenue-recognition date."}}}, "GenerateInvoiceResponse": {"allOf": [{"$ref": "#/components/schemas/InvoiceResponse", "description": "Composed schema segment for this value."}, {"type": "object", "description": "Composed schema segment for this value.", "required": ["already_existed"], "properties": {"already_existed": {"type": "boolean"}}}], "description": "Response for single-room invoice generation. Generation is idempotent on\n`(organization, room, period)`: a repeated call returns the existing\nnon-cancelled invoice unchanged with `already_existed = true` instead of a\n`409 invoice_already_generated`. The invoice fields are flattened at the top\nlevel so existing consumers keep reading `id`, `status`, `lines`, etc."}, "HealthResponse": {"type": "object", "description": "Health and readiness status payload.", "required": ["status", "service", "version"], "properties": {"status": {"type": "string", "description": "Current lifecycle or operational status."}, "service": {"type": "string", "description": "Service name that produced the status payload."}, "version": {"type": "string", "description": "Application version reported by the service."}}}, "HistoryStatus": {"type": "string", "description": "Status value as recorded in `room_status_history`. Read-only superset of the\noperational values plus the legacy occupancy values (`VACANT`/`OCCUPIED`)\nstill present in historical rows written before ADR 0017.", "enum": ["AVAILABLE", "VACANT", "OCCUPIED", "HIDDEN", "MAINTENANCE"]}, "ImportMeterReadingsRequest": {"type": "object", "description": "Request payload for import meter readings.", "required": ["property_id", "period", "csv"], "properties": {"property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "period": {"type": "string", "description": "Billing period in YYYY-MM format.", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}, "csv": {"type": "string", "description": "csv value for import meter readings request.", "maxLength": 200000, "minLength": 1}}}, "ImportRentersRequest": {"type": "object", "description": "Request payload for import renters.", "required": ["csv"], "properties": {"csv": {"type": "string", "description": "csv value for import renters request.", "maxLength": 200000, "minLength": 1}}}, "ImportResultResponse": {"type": "object", "description": "Response payload for import result.", "required": ["kind", "received_count", "imported_count", "skipped_count", "errors"], "properties": {"kind": {"type": "string", "description": "kind value for import result response."}, "received_count": {"type": "integer", "description": "received count value for import result response.", "minimum": 0}, "imported_count": {"type": "integer", "description": "imported count value for import result response.", "minimum": 0}, "skipped_count": {"type": "integer", "description": "Number of rooms skipped because an invoice already existed for the period.", "minimum": 0}, "errors": {"type": "array", "items": {"$ref": "#/components/schemas/ImportRowError"}, "description": "errors value for import result response."}}}, "ImportRoomsRequest": {"type": "object", "description": "Request payload for import rooms.", "required": ["property_id", "csv"], "properties": {"property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "csv": {"type": "string", "description": "csv value for import rooms request.", "maxLength": 200000, "minLength": 1}}}, "ImportRowError": {"type": "object", "description": "Schema for import row error.", "required": ["row", "field", "message"], "properties": {"row": {"type": "integer", "description": "row value for import row error.", "minimum": 0}, "field": {"type": "string", "description": "field value for import row error."}, "message": {"type": "string", "description": "Human-readable message safe to show in client logs or UI."}}}, "InvoiceDisplay": {"type": "object", "description": "Localized labels for the invoice header (ADR 0014). Additive: the raw\n`status` field is unchanged.", "required": ["status"], "properties": {"status": {"$ref": "#/components/schemas/DisplayLabel", "description": "Current lifecycle or operational status."}}}, "InvoiceLineDisplay": {"type": "object", "description": "Localized labels for an invoice line (ADR 0014).", "required": ["line_type"], "properties": {"line_type": {"$ref": "#/components/schemas/DisplayLabel", "description": "Invoice line classification used for totals."}}}, "InvoiceLineListResponse": {"type": "object", "description": "List response payload containing invoice line.", "required": ["lines"], "properties": {"lines": {"type": "array", "items": {"$ref": "#/components/schemas/InvoiceLineResponse"}, "description": "Invoice line items included in the invoice."}}}, "InvoiceLineResponse": {"type": "object", "description": "Response payload for invoice line.", "required": ["id", "line_type", "description", "quantity", "unit_price", "amount", "metadata", "display"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "line_type": {"$ref": "#/components/schemas/LineType", "description": "Invoice line classification used for totals."}, "description": {"type": "string", "description": "Human-readable description for the resource or line item."}, "quantity": {"type": "string", "description": "Quantity multiplier used for invoice line calculations.", "example": "1"}, "unit_price": {"type": "string", "description": "Unit price used for invoice line calculations.", "example": "1500000"}, "amount": {"type": "string", "description": "Money amount represented in the API currency unit.", "example": "1500000"}, "metadata": {"description": "Additional structured metadata attached to the record."}, "display": {"$ref": "#/components/schemas/InvoiceLineDisplay", "description": "display value for invoice line response."}}}, "InvoiceListResponse": {"type": "object", "description": "List response payload containing invoice.", "required": ["invoices"], "properties": {"invoices": {"type": "array", "items": {"$ref": "#/components/schemas/InvoiceResponse"}, "description": "Invoices returned by the response."}}}, "InvoiceQrResponse": {"type": "object", "description": "Response payload for invoice qr.", "required": ["invoice_id", "invoice_number", "period", "amount_due", "amount_due_vnd", "payment_reference", "payment_code", "transfer_content", "qr_payload_text", "reconciliation_enabled", "risk_notice"], "properties": {"invoice_id": {"type": "string", "format": "uuid", "description": "UUID identifier for invoice."}, "invoice_number": {"type": "string", "description": "Human-readable invoice number."}, "period": {"type": "string", "description": "Billing period in YYYY-MM format."}, "amount_due": {"type": "string", "description": "amount due value for invoice qr response."}, "amount_due_vnd": {"type": "integer", "format": "int64", "description": "amount due vnd value for invoice qr response."}, "payment_reference": {"type": "string", "description": "External or manual reference for payment reconciliation."}, "payment_code": {"type": "string", "description": "payment code value for invoice qr response."}, "transfer_content": {"type": "string", "description": "Server-rendered transfer content used for payment instructions and QR generation."}, "account_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for account."}, "bank_name": {"type": ["string", "null"], "description": "Bank name for the payment account."}, "sepay_bank_code": {"type": ["string", "null"], "description": "sepay bank code value for invoice qr response."}, "bank_account_number": {"type": ["string", "null"], "description": "Bank account number used for tenant transfers."}, "bank_account_holder": {"type": ["string", "null"], "description": "Name of the bank account holder for transfers."}, "qr_payload_text": {"type": "string", "description": "qr payload text value for invoice qr response."}, "qr_image_url": {"type": ["string", "null"], "description": "qr image url value for invoice qr response."}, "reconciliation_enabled": {"type": "boolean", "description": "reconciliation enabled value for invoice qr response."}, "risk_notice": {"type": "string", "description": "risk notice value for invoice qr response."}}}, "InvoiceResponse": {"type": "object", "description": "Response payload for invoice.", "required": ["id", "organization_id", "property_id", "room_id", "renter_id", "lease_id", "period", "invoice_number", "status", "display", "effective_status", "effective_display", "due_date", "total_amount", "paid_amount", "payment_reference", "payment_code", "lines", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "renter_id": {"type": "string", "format": "uuid", "description": "UUID identifier for renter."}, "lease_id": {"type": "string", "format": "uuid", "description": "UUID identifier for lease."}, "period": {"type": "string", "description": "Billing period in YYYY-MM format."}, "invoice_number": {"type": "string", "description": "Human-readable invoice number."}, "status": {"$ref": "#/components/schemas/InvoiceStatus", "description": "Persisted lifecycle/storage status. Issuing an unpaid invoice whose due\ndate is before the issue date stores OVERDUE immediately; otherwise use\n`effective_status` for current UI rendering because overdue can also be\nderived later from due date and remaining balance."}, "display": {"$ref": "#/components/schemas/InvoiceDisplay", "description": "display value for invoice response."}, "effective_status": {"$ref": "#/components/schemas/InvoiceStatus", "description": "Backend-owned current invoice state for UI/reporting. Past-due issued or\npartially paid invoices with remaining balance are represented as OVERDUE."}, "effective_display": {"$ref": "#/components/schemas/InvoiceDisplay", "description": "effective display value for invoice response."}, "issue_date": {"type": ["string", "null"], "format": "date", "description": "Date when the invoice was issued."}, "due_date": {"type": "string", "format": "date", "description": "Date when the invoice is due."}, "total_amount": {"type": "string", "description": "Total invoice, payment, or report amount.", "example": "1500000"}, "paid_amount": {"type": "string", "description": "Amount already paid toward the invoice or period total.", "example": "0"}, "payment_reference": {"type": "string", "description": "External or manual reference for payment reconciliation."}, "payment_code": {"type": "string", "description": "payment code value for invoice response."}, "cancel_reason": {"type": ["string", "null"], "description": "cancel reason value for invoice response."}, "lines": {"type": "array", "items": {"$ref": "#/components/schemas/InvoiceLineResponse"}, "description": "Invoice line items included in the invoice."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "InvoiceStatus": {"type": "string", "description": "Lifecycle status for an invoice.", "enum": ["DRAFT", "ISSUED", "PARTIALLY_PAID", "PAID", "OVERDUE", "CANCELLED"]}, "IssueInvoiceRequest": {"type": "object", "description": "Request payload for issue invoice.", "required": ["issue_date"], "properties": {"issue_date": {"type": "string", "format": "date", "description": "Date when the invoice was issued."}}}, "ItemListResponse": {"type": "object", "description": "List response payload containing item.", "required": ["items", "meta"], "properties": {"items": {"type": "array", "items": {}, "description": "items value for item list response."}, "meta": {"$ref": "#/components/schemas/CursorMeta", "description": "Response metadata such as pagination counts."}}}, "LabelsFormOptions": {"type": "object", "description": "API-owned dropdown options (ADR 0014 Phase 3). Mirrors the public\ntenant-portal `form_options` so a single source of truth serves every form.", "required": ["maintenance_priorities"], "properties": {"maintenance_priorities": {"type": "array", "items": {"$ref": "#/components/schemas/DisplayLabel"}, "description": "maintenance priorities value for labels form options."}}}, "LabelsResponse": {"type": "object", "description": "Localized dictionaries for every covered domain enum (ADR 0014 Phase 3).\nEach entry is a stable `value` + its localized `label`. Lets clients render\nany enum without a hardcoded enum\u2192label table.", "required": ["invoice_status", "line_type", "payment_method", "payment_status", "maintenance_priority", "maintenance_status", "form_options"], "properties": {"invoice_status": {"type": "array", "items": {"$ref": "#/components/schemas/DisplayLabel"}, "description": "invoice status value for labels response."}, "line_type": {"type": "array", "items": {"$ref": "#/components/schemas/DisplayLabel"}, "description": "Invoice line classification used for totals."}, "payment_method": {"type": "array", "items": {"$ref": "#/components/schemas/DisplayLabel"}, "description": "payment method value for labels response."}, "payment_status": {"type": "array", "items": {"$ref": "#/components/schemas/DisplayLabel"}, "description": "payment status value for labels response."}, "maintenance_priority": {"type": "array", "items": {"$ref": "#/components/schemas/DisplayLabel"}, "description": "maintenance priority value for labels response."}, "maintenance_status": {"type": "array", "items": {"$ref": "#/components/schemas/DisplayLabel"}, "description": "maintenance status value for labels response."}, "form_options": {"$ref": "#/components/schemas/LabelsFormOptions", "description": "form options value for labels response."}}}, "LeaseListResponse": {"type": "object", "description": "List response payload containing lease.", "required": ["leases"], "properties": {"leases": {"type": "array", "items": {"$ref": "#/components/schemas/LeaseResponse"}, "description": "Leases returned by the response."}}}, "LeaseResponse": {"type": "object", "description": "Response payload for lease.", "required": ["id", "organization_id", "property_id", "room_id", "renter_id", "status", "start_date", "monthly_rent", "deposit_amount", "number_of_occupants", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "renter_id": {"type": "string", "format": "uuid", "description": "UUID identifier for renter."}, "status": {"$ref": "#/components/schemas/LeaseStatus", "description": "Current lifecycle or operational status."}, "start_date": {"type": "string", "format": "date", "description": "Lease or report start date."}, "end_date": {"type": ["string", "null"], "format": "date", "description": "Lease or report end date."}, "monthly_rent": {"type": "string", "description": "Monthly rent amount for the lease.", "example": "3000000"}, "deposit_amount": {"type": "string", "description": "Deposit amount recorded for the lease.", "example": "3000000"}, "number_of_occupants": {"type": "integer", "format": "int32", "description": "Number of occupants assigned to the room or lease."}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "LeaseStatus": {"type": "string", "description": "Lifecycle status for a lease.", "enum": ["ACTIVE", "ENDED", "CANCELLED"]}, "LineType": {"type": "string", "description": "Invoice line classification used for totals and discount rules.", "enum": ["rent", "electricity", "water", "recurring_fee", "other_charge", "discount"]}, "ListingFilterOptionsResponse": {"type": "object", "description": "Response payload for listing filter options.", "required": ["provinces", "wards", "amenities"], "properties": {"provinces": {"type": "array", "items": {"$ref": "#/components/schemas/FilterOption"}, "description": "provinces value for listing filter options response."}, "wards": {"type": "array", "items": {"$ref": "#/components/schemas/FilterOption"}, "description": "wards value for listing filter options response."}, "amenities": {"type": "array", "items": {"$ref": "#/components/schemas/AmenityOption"}, "description": "amenities value for listing filter options response."}}}, "ListingImageResponse": {"type": "object", "description": "Response payload for listing image.", "required": ["id", "image_url", "sort_order"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "media_asset_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for media asset."}, "image_url": {"type": "string", "description": "image url value for listing image response."}, "alt_text": {"type": ["string", "null"], "description": "alt text value for listing image response."}, "sort_order": {"type": "integer", "format": "int32", "description": "sort order value for listing image response."}}}, "ListingInquiryListResponse": {"type": "object", "description": "List response payload containing listing inquiry.", "required": ["inquiries"], "properties": {"inquiries": {"type": "array", "items": {"$ref": "#/components/schemas/ListingInquiryResponse"}, "description": "inquiries value for listing inquiry list response."}}}, "ListingInquiryResponse": {"type": "object", "description": "Response payload for listing inquiry.", "required": ["id", "organization_id", "property_id", "room_id", "listing_id", "listing_slug", "property_name", "room_name", "renter_name", "phone", "message", "status", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "listing_id": {"type": "string", "format": "uuid", "description": "UUID identifier for listing."}, "listing_slug": {"type": "string", "description": "listing slug value for listing inquiry response."}, "property_name": {"type": "string", "description": "Human-readable property name."}, "room_name": {"type": "string", "description": "Human-readable room name."}, "renter_name": {"type": "string", "description": "Human-readable renter name."}, "phone": {"type": "string", "description": "Phone number associated with the renter or user."}, "email": {"type": ["string", "null"], "description": "Email address associated with the user or renter."}, "message": {"type": "string", "description": "Human-readable message safe to show in client logs or UI."}, "status": {"$ref": "#/components/schemas/ListingInquiryStatus", "description": "Current lifecycle or operational status."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "ListingInquiryStatus": {"type": "string", "description": "Inquiry lifecycle state. Tenants only ever create `New`; the landlord moves\nit through review on the admin surface.", "enum": ["NEW", "REVIEWED", "CLOSED"]}, "ListingLocationDisplay": {"type": "object", "description": "Localized presentation for a public listing's location (ADR 0014/0015).\nAdditive: the raw `city`/`district`/`ward` fields are unchanged. `city` is the\nlocalized 2-tier province name, `ward` the localized ward name (issue #18\nresolver); `district` echoes the legacy raw value (the 2025 model is 2-tier).", "properties": {"city": {"type": ["string", "null"], "description": "City portion of the address."}, "district": {"type": ["string", "null"], "description": "District portion of the address."}, "ward": {"type": ["string", "null"], "description": "Ward portion of the address."}, "address_area": {"type": ["string", "null"], "description": "A single composed, localized area line, or null when no parts exist."}}}, "LoginRequest": {"type": "object", "description": "Request payload for login.", "required": ["username_or_email", "password"], "properties": {"username_or_email": {"type": "string", "description": "Username or email accepted for login.", "minLength": 1}, "password": {"type": "string", "description": "Plaintext password accepted only in authentication requests.", "minLength": 1}}}, "LogoutRequest": {"type": "object", "description": "Request payload for logout.", "properties": {"refresh_token": {"type": ["string", "null"], "description": "Optional when the refresh token is supplied via the httpOnly cookie."}}}, "LogoutResponse": {"type": "object", "description": "Response payload for logout.", "required": ["logged_out"], "properties": {"logged_out": {"type": "boolean", "description": "Whether logout completed successfully."}}}, "MaintenanceTicketDisplay": {"type": "object", "description": "Localized labels for a maintenance ticket (ADR 0014). Additive: the raw\n`priority`/`status` fields are unchanged.", "required": ["priority", "status"], "properties": {"priority": {"$ref": "#/components/schemas/DisplayLabel", "description": "priority value for maintenance ticket display."}, "status": {"$ref": "#/components/schemas/DisplayLabel", "description": "Current lifecycle or operational status."}}}, "MaintenanceTicketListResponse": {"type": "object", "description": "List response payload containing maintenance ticket.", "required": ["tickets"], "properties": {"tickets": {"type": "array", "items": {"$ref": "#/components/schemas/MaintenanceTicketResponse"}, "description": "tickets value for maintenance ticket list response."}}}, "MaintenanceTicketPriority": {"type": "string", "description": "Schema for maintenance ticket priority.", "enum": ["LOW", "NORMAL", "HIGH", "URGENT"]}, "MaintenanceTicketResponse": {"type": "object", "description": "Response payload for maintenance ticket.", "required": ["id", "organization_id", "property_id", "title", "description", "priority", "status", "display", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "room_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for room."}, "renter_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for renter."}, "invoice_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for invoice."}, "title": {"type": "string", "description": "title value for maintenance ticket response."}, "description": {"type": "string", "description": "Human-readable description for the resource or line item."}, "priority": {"$ref": "#/components/schemas/MaintenanceTicketPriority", "description": "priority value for maintenance ticket response."}, "status": {"$ref": "#/components/schemas/MaintenanceTicketStatus", "description": "Current lifecycle or operational status."}, "display": {"$ref": "#/components/schemas/MaintenanceTicketDisplay", "description": "display value for maintenance ticket response."}, "reported_by_name": {"type": ["string", "null"], "description": "reported by name value for maintenance ticket response."}, "reported_by_contact": {"type": ["string", "null"], "description": "reported by contact value for maintenance ticket response."}, "created_by": {"type": ["string", "null"], "format": "uuid", "description": "User id that created the resource."}, "resolved_at": {"type": ["string", "null"], "format": "date-time", "description": "resolved at value for maintenance ticket response."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "MaintenanceTicketStatus": {"type": "string", "description": "Schema for maintenance ticket status.", "enum": ["OPEN", "IN_PROGRESS", "RESOLVED", "CANCELLED"]}, "MatchPaymentRequest": {"type": "object", "description": "Request payload for match payment.", "required": ["invoice_id", "amount", "payment_date", "bank_transaction_reference"], "properties": {"invoice_id": {"type": "string", "format": "uuid", "description": "UUID identifier for invoice."}, "amount": {"type": "string", "description": "2-dp decimal string; validated > 0 when the payment is recorded.", "example": "1500000"}, "payment_date": {"type": "string", "format": "date", "description": "Date when the payment was received or recorded."}, "bank_transaction_reference": {"type": "string", "description": "bank transaction reference value for match payment request.", "maxLength": 160, "minLength": 1}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "MatchPaymentResponse": {"type": "object", "description": "Response payload for match payment.", "required": ["payment", "reconciliation_enabled"], "properties": {"payment": {"$ref": "#/components/schemas/PaymentResponse", "description": "payment value for match payment response."}, "reconciliation_enabled": {"type": "boolean", "description": "reconciliation enabled value for match payment response."}}}, "MatchReviewItemRequest": {"type": "object", "description": "Request payload for match review item.", "required": ["invoice_id", "payment_date", "note"], "properties": {"invoice_id": {"type": "string", "format": "uuid", "description": "UUID identifier for invoice."}, "payment_date": {"type": "string", "format": "date", "description": "Date when the payment was received or recorded."}, "note": {"type": "string", "description": "Optional note captured by the operator.", "maxLength": 1000, "minLength": 1}}}, "MatchReviewItemResponse": {"type": "object", "description": "Response payload for match review item.", "required": ["review_item", "payment"], "properties": {"review_item": {"$ref": "#/components/schemas/ReviewItemResponse", "description": "review item value for match review item response."}, "payment": {"$ref": "#/components/schemas/PaymentResponse", "description": "payment value for match review item response."}}}, "MeResponse": {"type": "object", "description": "Response payload for me.", "required": ["user", "active_organization", "memberships"], "properties": {"user": {"$ref": "#/components/schemas/UserInfo", "description": "User profile returned by the response."}, "active_organization": {"$ref": "#/components/schemas/OrganizationInfo", "description": "Organization context resolved for the authenticated request."}, "memberships": {"type": "array", "items": {"$ref": "#/components/schemas/OrganizationInfo"}, "description": "Memberships visible to the authenticated user."}}}, "MediaUploadRequest": {"type": "object", "description": "Request payload for media upload.", "required": ["file", "purpose", "entity_type", "entity_id"], "properties": {"file": {"type": "string", "format": "binary", "description": "file value for media upload request."}, "purpose": {"type": "string", "description": "purpose value for media upload request."}, "entity_type": {"type": "string", "description": "Type name of the audited entity."}, "entity_id": {"type": "string", "format": "uuid", "description": "Identifier of the audited entity."}}}, "MediaUploadResponse": {"type": "object", "description": "Response payload for media upload.", "required": ["id", "purpose", "entity_type", "entity_id", "image_url", "object_key", "content_type", "size_bytes"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "purpose": {"type": "string", "description": "purpose value for media upload response."}, "entity_type": {"type": "string", "description": "Type name of the audited entity."}, "entity_id": {"type": "string", "format": "uuid", "description": "Identifier of the audited entity."}, "image_url": {"type": "string", "description": "image url value for media upload response."}, "object_key": {"type": "string", "description": "object key value for media upload response."}, "content_type": {"type": "string", "description": "content type value for media upload response."}, "size_bytes": {"type": "integer", "format": "int64", "description": "size bytes value for media upload response."}}}, "MessageResponse": {"type": "object", "description": "Response payload for message.", "required": ["message"], "properties": {"message": {"type": "string", "description": "Human-readable message safe to show in client logs or UI."}}}, "MeterReadingListResponse": {"type": "object", "description": "List response payload containing meter reading.", "required": ["meter_readings"], "properties": {"meter_readings": {"type": "array", "items": {"$ref": "#/components/schemas/MeterReadingResponse"}, "description": "Meter readings returned by the response."}}}, "MeterReadingResponse": {"type": "object", "description": "Response payload for meter reading.", "required": ["id", "organization_id", "property_id", "room_id", "period", "recorded_at", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "period": {"type": "string", "description": "Billing period in YYYY-MM format."}, "electricity_previous": {"type": ["number", "null"], "format": "double", "description": "Previous electricity meter reading for the billing period."}, "electricity_current": {"type": ["number", "null"], "format": "double", "description": "Current electricity meter reading for the billing period."}, "water_previous": {"type": ["number", "null"], "format": "double", "description": "Previous water meter reading for the billing period."}, "water_current": {"type": ["number", "null"], "format": "double", "description": "Current water meter reading for the billing period."}, "recorded_at": {"type": "string", "format": "date-time", "description": "Timestamp when the event or payment was recorded."}, "recorded_by": {"type": ["string", "null"], "format": "uuid", "description": "User id that recorded the event or payment."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "MeterReadingStatus": {"type": "string", "description": "Meter-reading completeness for a room in one billing period.", "enum": ["NONE", "PARTIAL", "COMPLETE"]}, "MfaConfirmResponse": {"type": "object", "description": "Response payload for mfa confirm.", "required": ["recovery_codes"], "properties": {"recovery_codes": {"type": "array", "items": {"type": "string"}, "description": "recovery codes value for mfa confirm response."}}}, "MfaEnrollmentResponse": {"type": "object", "description": "Response payload for mfa enrollment.", "required": ["secret", "provisioning_uri"], "properties": {"secret": {"type": "string", "description": "secret value for mfa enrollment response."}, "provisioning_uri": {"type": "string", "description": "provisioning uri value for mfa enrollment response."}}}, "OAuthExchangeRequest": {"type": "object", "description": "Request payload for o auth exchange.", "required": ["handoff_code"], "properties": {"handoff_code": {"type": "string", "description": "handoff code value for o auth exchange request.", "maxLength": 160, "minLength": 1}}}, "OAuthExchangeResponse": {"type": "object", "description": "Response payload for o auth exchange.", "required": ["status"], "properties": {"status": {"$ref": "#/components/schemas/OAuthExchangeStatus", "description": "Current lifecycle or operational status."}, "auth": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/AuthResponse"}], "description": "auth value for o auth exchange response."}, "signup": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/OAuthSignupRequiredResponse"}], "description": "signup value for o auth exchange response."}}}, "OAuthExchangeStatus": {"type": "string", "description": "Schema for o auth exchange status.", "enum": ["authenticated", "signup_required"]}, "OAuthProviderInfo": {"type": "object", "description": "Schema for o auth provider info.", "required": ["provider", "label"], "properties": {"provider": {"$ref": "#/components/schemas/SocialProvider", "description": "provider value for o auth provider info."}, "label": {"type": "string", "description": "label value for o auth provider info."}}}, "OAuthProvidersResponse": {"type": "object", "description": "Response payload for o auth providers.", "required": ["providers"], "properties": {"providers": {"type": "array", "items": {"$ref": "#/components/schemas/OAuthProviderInfo"}, "description": "providers value for o auth providers response."}}}, "OAuthSignupRequiredResponse": {"type": "object", "description": "Response payload for o auth signup required.", "required": ["signup_token", "provider"], "properties": {"signup_token": {"type": "string", "description": "signup token value for o auth signup required response."}, "provider": {"$ref": "#/components/schemas/SocialProvider", "description": "provider value for o auth signup required response."}, "email": {"type": ["string", "null"], "description": "Email address associated with the user or renter."}, "display_name": {"type": ["string", "null"], "description": "Human-readable display name."}}}, "OccupancyReportResponse": {"type": "object", "description": "Response payload for occupancy report.", "required": ["total_rooms", "occupied_rooms", "vacant_rooms", "maintenance_rooms", "hidden_rooms", "occupancy_rate", "rows"], "properties": {"property_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for property."}, "total_rooms": {"type": "integer", "format": "int64", "description": "Total number of rooms in scope."}, "occupied_rooms": {"type": "integer", "format": "int64", "description": "Number of occupied rooms."}, "vacant_rooms": {"type": "integer", "format": "int64", "description": "Number of rooms currently vacant."}, "maintenance_rooms": {"type": "integer", "format": "int64", "description": "Rooms currently marked for maintenance."}, "hidden_rooms": {"type": "integer", "format": "int64", "description": "Rooms excluded from active availability views."}, "occupancy_rate": {"type": "number", "format": "double", "description": "Occupied room ratio represented as a decimal value."}, "rows": {"type": "array", "items": {"$ref": "#/components/schemas/OccupancyReportRow"}, "description": "Report rows returned by the response."}}}, "OccupancyReportRow": {"type": "object", "description": "Report row payload for occupancy report.", "required": ["property_id", "property_name", "total_rooms", "occupied_rooms", "vacant_rooms", "maintenance_rooms", "hidden_rooms", "occupancy_rate"], "properties": {"property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "property_name": {"type": "string", "description": "Human-readable property name."}, "total_rooms": {"type": "integer", "format": "int64", "description": "Total number of rooms in scope."}, "occupied_rooms": {"type": "integer", "format": "int64", "description": "Number of occupied rooms."}, "vacant_rooms": {"type": "integer", "format": "int64", "description": "Number of rooms currently vacant."}, "maintenance_rooms": {"type": "integer", "format": "int64", "description": "Rooms currently marked for maintenance."}, "hidden_rooms": {"type": "integer", "format": "int64", "description": "Rooms excluded from active availability views."}, "occupancy_rate": {"type": "number", "format": "double", "description": "Occupied room ratio represented as a decimal value."}}}, "OnboardingAccountRequest": {"type": "object", "description": "Request payload for onboarding account.", "required": ["username", "password"], "properties": {"username": {"type": "string", "description": "Unique username used for login and display.", "maxLength": 50, "minLength": 3}, "email": {"type": ["string", "null"], "format": "email", "description": "Email address associated with the user or renter.", "maxLength": 254}, "password": {"type": "string", "description": "Plaintext password accepted only in authentication requests.", "maxLength": 1024, "minLength": 8}, "display_name": {"type": ["string", "null"], "description": "Human-readable display name.", "maxLength": 100}}}, "OnboardingOrganizationRequest": {"type": "object", "description": "Request payload for onboarding organization.", "required": ["name"], "properties": {"name": {"type": "string", "description": "Human-readable name for the resource.", "maxLength": 100, "minLength": 2}}}, "OnboardingSetupRequest": {"type": "object", "description": "Request payload for onboarding setup.", "required": ["account", "organization", "property", "billing_settings", "rooms"], "properties": {"account": {"$ref": "#/components/schemas/OnboardingAccountRequest", "description": "account value for onboarding setup request."}, "organization": {"$ref": "#/components/schemas/OnboardingOrganizationRequest", "description": "Organization record included in the response."}, "property": {"$ref": "#/components/schemas/CreatePropertyRequest", "description": "property value for onboarding setup request."}, "billing_settings": {"$ref": "#/components/schemas/UpsertBillingSettingsRequest", "description": "billing settings value for onboarding setup request."}, "rooms": {"$ref": "#/components/schemas/BulkCreateRoomsRequest", "description": "Rooms returned by the response."}}}, "OnboardingSetupResponse": {"type": "object", "description": "Response payload for onboarding setup.", "required": ["access_token", "refresh_token", "user", "organization", "property", "billing_settings", "rooms"], "properties": {"access_token": {"type": "string", "description": "Short-lived bearer token used in the Authorization header."}, "refresh_token": {"type": "string", "description": "Longer-lived token used only to refresh or revoke sessions."}, "user": {"$ref": "#/components/schemas/UserInfo", "description": "User profile returned by the response."}, "organization": {"$ref": "#/components/schemas/OrganizationInfo", "description": "Organization record included in the response."}, "property": {"$ref": "#/components/schemas/PropertyResponse", "description": "property value for onboarding setup response."}, "billing_settings": {"$ref": "#/components/schemas/BillingSettingsResponse", "description": "billing settings value for onboarding setup response."}, "rooms": {"type": "array", "items": {"$ref": "#/components/schemas/RoomResponse"}, "description": "Rooms returned by the response."}}}, "OperationalStatus": {"type": "string", "description": "The operational state actually stored in `rooms.status` (ADR 0017).\nOccupancy is not stored here \u2014 it is derived from active leases.", "enum": ["AVAILABLE", "HIDDEN", "MAINTENANCE"]}, "OrganizationDetailResponse": {"type": "object", "description": "Response payload for organization detail.", "required": ["organization"], "properties": {"organization": {"$ref": "#/components/schemas/OrganizationResponse", "description": "Organization record included in the response."}}}, "OrganizationInfo": {"type": "object", "description": "Schema for organization info.", "required": ["id", "name", "slug", "role"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "name": {"type": "string", "description": "Human-readable name for the resource."}, "slug": {"type": "string", "description": "URL-safe slug for the resource."}, "role": {"$ref": "#/components/schemas/OrganizationRole", "description": "Role granted to the user in the relevant scope."}}}, "OrganizationListResponse": {"type": "object", "description": "List response payload containing organization.", "required": ["organizations"], "properties": {"organizations": {"type": "array", "items": {"$ref": "#/components/schemas/OrganizationInfo"}, "description": "Organizations returned by the response."}}}, "OrganizationMemberResponse": {"type": "object", "description": "Response payload for organization member.", "required": ["membership_id", "organization_id", "organization_name", "organization_slug", "organization_status", "organization_plan_code", "user_id", "username", "role", "membership_status", "membership_created_at", "membership_updated_at"], "properties": {"membership_id": {"type": "string", "format": "uuid", "description": "UUID identifier for membership."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "organization_name": {"type": "string", "description": "Human-readable organization name."}, "organization_slug": {"type": "string", "description": "URL-safe organization slug."}, "organization_status": {"type": "string", "description": "Operational status of the organization."}, "organization_plan_code": {"type": "string", "description": "Plan code assigned to the organization."}, "user_id": {"type": "string", "format": "uuid", "description": "UUID identifier for user."}, "username": {"type": "string", "description": "Unique username used for login and display."}, "email": {"type": ["string", "null"], "description": "Email address associated with the user or renter."}, "display_name": {"type": ["string", "null"], "description": "Human-readable display name."}, "role": {"$ref": "#/components/schemas/OrganizationRole", "description": "Role granted to the user in the relevant scope."}, "membership_status": {"type": "string", "description": "Current membership status."}, "membership_created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the membership was created."}, "membership_updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the membership was last updated."}}}, "OrganizationMembersResponse": {"type": "object", "description": "Response payload for organization members.", "required": ["members"], "properties": {"members": {"type": "array", "items": {"$ref": "#/components/schemas/OrganizationMemberResponse"}, "description": "Organization members returned by the response."}}}, "OrganizationResponse": {"type": "object", "description": "Response payload for organization.", "required": ["id", "name", "slug", "status", "plan_code", "tax_method", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "name": {"type": "string", "description": "Human-readable name for the resource."}, "slug": {"type": "string", "description": "URL-safe slug for the resource."}, "status": {"type": "string", "description": "Current lifecycle or operational status."}, "plan_code": {"type": "string", "description": "Commercial plan code assigned to an organization."}, "tax_method": {"$ref": "#/components/schemas/TaxMethod", "description": "Tax filing method (`none` | `ca_nhan` | `ke_khai`). Gates future legal\ne-invoice issuance (ADR 0018); behavior-neutral today."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "OrganizationRole": {"type": "string", "description": "Organization-scoped role used by RBAC checks.", "enum": ["OWNER", "ADMIN", "OPERATOR", "ACCOUNTANT", "VIEWER"]}, "OverdueInvoiceSummary": {"type": "object", "description": "Schema for overdue invoice summary.", "required": ["invoice_id", "invoice_number", "property_id", "property_name", "room_id", "room_name", "renter_id", "renter_name", "due_date", "total_amount", "paid_amount", "unpaid_amount"], "properties": {"invoice_id": {"type": "string", "format": "uuid", "description": "UUID identifier for invoice."}, "invoice_number": {"type": "string", "description": "Human-readable invoice number."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "property_name": {"type": "string", "description": "Human-readable property name."}, "room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "room_name": {"type": "string", "description": "Human-readable room name."}, "renter_id": {"type": "string", "format": "uuid", "description": "UUID identifier for renter."}, "renter_name": {"type": "string", "description": "Human-readable renter name."}, "due_date": {"type": "string", "format": "date", "description": "Date when the invoice is due."}, "total_amount": {"type": "string", "description": "Total invoice, payment, or report amount."}, "paid_amount": {"type": "string", "description": "Amount already paid toward the invoice or period total."}, "unpaid_amount": {"type": "string", "description": "Amount still unpaid for the invoice or report row."}}}, "OwnerDeviceResponse": {"type": "object", "description": "Response payload for owner device.", "required": ["id", "platform", "device_token", "created_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "platform": {"type": "string", "description": "platform value for owner device response."}, "device_token": {"type": "string", "description": "device token value for owner device response."}, "label": {"type": ["string", "null"], "description": "label value for owner device response."}, "app_version": {"type": ["string", "null"], "description": "app version value for owner device response."}, "build_number": {"type": ["string", "null"], "description": "build number value for owner device response."}, "os_version": {"type": ["string", "null"], "description": "os version value for owner device response."}, "device_model": {"type": ["string", "null"], "description": "device model value for owner device response."}, "environment": {"type": ["string", "null"], "description": "environment value for owner device response."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}}}, "OwnerNotificationPreferencesResponse": {"type": "object", "description": "Response payload for owner notification preferences.", "required": ["email_enabled", "push_enabled", "invoice_updates", "maintenance_updates", "message_updates", "updated_at"], "properties": {"email_enabled": {"type": "boolean", "description": "email enabled value for owner notification preferences response."}, "push_enabled": {"type": "boolean", "description": "push enabled value for owner notification preferences response."}, "invoice_updates": {"type": "boolean", "description": "invoice updates value for owner notification preferences response."}, "maintenance_updates": {"type": "boolean", "description": "maintenance updates value for owner notification preferences response."}, "message_updates": {"type": "boolean", "description": "message updates value for owner notification preferences response."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "OwnerRegisterDeviceRequest": {"type": "object", "description": "Request payload for owner register device.", "required": ["platform", "device_token"], "properties": {"platform": {"type": "string", "description": "platform value for owner register device request.", "maxLength": 20, "minLength": 1}, "device_token": {"type": "string", "description": "device token value for owner register device request.", "maxLength": 4096, "minLength": 1}, "label": {"type": ["string", "null"], "description": "label value for owner register device request.", "maxLength": 120}, "app_version": {"type": ["string", "null"], "description": "app version value for owner register device request."}, "build_number": {"type": ["string", "null"], "description": "build number value for owner register device request."}, "os_version": {"type": ["string", "null"], "description": "os version value for owner register device request."}, "device_model": {"type": ["string", "null"], "description": "device model value for owner register device request."}, "environment": {"type": ["string", "null"], "description": "environment value for owner register device request."}}}, "OwnerUpdateNotificationPreferencesRequest": {"type": "object", "description": "Request payload for owner update notification preferences.", "properties": {"email_enabled": {"type": ["boolean", "null"], "description": "email enabled value for owner update notification preferences request."}, "push_enabled": {"type": ["boolean", "null"], "description": "push enabled value for owner update notification preferences request."}, "invoice_updates": {"type": ["boolean", "null"], "description": "invoice updates value for owner update notification preferences request."}, "maintenance_updates": {"type": ["boolean", "null"], "description": "maintenance updates value for owner update notification preferences request."}, "message_updates": {"type": ["boolean", "null"], "description": "message updates value for owner update notification preferences request."}}}, "PaymentAccountListResponse": {"type": "object", "description": "List response payload containing payment account.", "required": ["payment_accounts"], "properties": {"payment_accounts": {"type": "array", "items": {"$ref": "#/components/schemas/PaymentAccountResponse"}, "description": "Payment accounts returned by the response."}}}, "PaymentAccountResponse": {"type": "object", "description": "Response payload for payment account.", "required": ["id", "organization_id", "source", "verification_status", "is_default", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for property."}, "bank_name": {"type": ["string", "null"], "description": "Bank name for the payment account."}, "sepay_bank_code": {"type": ["string", "null"], "description": "sepay bank code value for payment account response."}, "bank_code": {"type": ["string", "null"], "description": "bank code value for payment account response."}, "source": {"type": "string", "description": "External or internal source that supplied the response data."}, "verification_status": {"type": "string", "description": "verification status value for payment account response."}, "sepay_bank_account_xid": {"type": ["string", "null"], "description": "sepay bank account xid value for payment account response."}, "sepay_connection_status": {"type": ["string", "null"], "description": "sepay connection status value for payment account response."}, "sepay_last_synced_at": {"type": ["string", "null"], "format": "date-time", "description": "sepay last synced at value for payment account response."}, "bank_account_number": {"type": ["string", "null"], "description": "Bank account number used for tenant transfers."}, "bank_account_holder": {"type": ["string", "null"], "description": "Name of the bank account holder for transfers."}, "is_default": {"type": "boolean", "description": "Whether this account or setting is the default choice."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "PaymentBankListResponse": {"type": "object", "description": "List response payload containing payment bank.", "required": ["banks", "source", "cached_at", "stale"], "properties": {"banks": {"type": "array", "items": {"$ref": "#/components/schemas/PaymentBankResponse"}, "description": "Payment bank reference rows returned by the bank directory endpoint."}, "source": {"type": "string", "description": "External or internal source that supplied the response data."}, "cached_at": {"type": "string", "format": "date-time", "description": "Timestamp when the bank directory cache was last refreshed."}, "stale": {"type": "boolean", "description": "True when the response is served from expired cache because the upstream provider is unavailable."}}}, "PaymentBankResponse": {"type": "object", "description": "Response payload for payment bank.", "required": ["id", "name", "short_name", "code", "bin", "transfer_supported", "lookup_supported", "provider"], "properties": {"id": {"type": "string", "description": "Provider bank identifier from VietQR. Use code for payment_accounts.sepay_bank_code and billing integrations."}, "name": {"type": "string", "description": "Human-readable name for the resource."}, "short_name": {"type": "string", "description": "short name value for payment bank response."}, "code": {"type": "string", "description": "VietQR/NAPAS bank code used as payment_accounts.sepay_bank_code for QR and billing integrations."}, "bin": {"type": "string", "description": "NAPAS/VietQR bank BIN used by QR and account lookup providers."}, "logo_url": {"type": ["string", "null"], "description": "Public logo URL for the bank, when the directory provider supplies one."}, "transfer_supported": {"type": "boolean", "description": "Whether this bank supports VietQR transfer generation."}, "lookup_supported": {"type": "boolean", "description": "Whether this bank supports VietQR account lookup through the provider."}, "provider": {"type": "string", "description": "provider value for payment bank response."}}}, "PaymentDisplay": {"type": "object", "description": "Localized labels for a payment (ADR 0014). Additive: the raw `method`/`status`\nfields are unchanged.", "required": ["method", "status"], "properties": {"method": {"$ref": "#/components/schemas/DisplayLabel", "description": "Payment method used for the payment."}, "status": {"$ref": "#/components/schemas/DisplayLabel", "description": "Current lifecycle or operational status."}}}, "PaymentListResponse": {"type": "object", "description": "List response payload containing payment.", "required": ["payments"], "properties": {"payments": {"type": "array", "items": {"$ref": "#/components/schemas/PaymentResponse"}, "description": "Payments returned by the response."}}}, "PaymentMethod": {"type": "string", "description": "Manual payment method classification.", "enum": ["cash", "bank_transfer", "other"]}, "PaymentReconciliationSettingsResponse": {"type": "object", "description": "Response payload for payment reconciliation settings.", "required": ["organization_id", "enabled", "webhook_mode", "sepay_payment_code_prefix", "sepay_webhook_configured", "risk_notice"], "properties": {"organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "enabled": {"type": "boolean", "description": "enabled value for payment reconciliation settings response."}, "bank_provider": {"type": ["string", "null"], "description": "bank provider value for payment reconciliation settings response."}, "webhook_mode": {"type": "string", "description": "webhook mode value for payment reconciliation settings response."}, "sepay_payment_code_prefix": {"type": "string", "description": "sepay payment code prefix value for payment reconciliation settings response."}, "sepay_webhook_public_id": {"type": ["string", "null"], "description": "UUID identifier for sepay webhook public."}, "sepay_webhook_url_path": {"type": ["string", "null"], "description": "sepay webhook url path value for payment reconciliation settings response."}, "sepay_webhook_configured": {"type": "boolean", "description": "sepay webhook configured value for payment reconciliation settings response."}, "risk_acknowledged_at": {"type": ["string", "null"], "format": "date-time", "description": "risk acknowledged at value for payment reconciliation settings response."}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator."}, "created_at": {"type": ["string", "null"], "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": ["string", "null"], "format": "date-time", "description": "Timestamp when the resource was last updated."}, "risk_notice": {"type": "string", "description": "risk notice value for payment reconciliation settings response."}}}, "PaymentResponse": {"type": "object", "description": "Response payload for payment.", "required": ["id", "organization_id", "amount", "method", "payment_date", "status", "display", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "invoice_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for invoice."}, "renter_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for renter."}, "room_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for room."}, "amount": {"type": "string", "description": "Money amount represented in the API currency unit.", "example": "1500000"}, "method": {"$ref": "#/components/schemas/PaymentMethod", "description": "Payment method used for the payment."}, "payment_date": {"type": "string", "format": "date", "description": "Date when the payment was received or recorded."}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator."}, "status": {"$ref": "#/components/schemas/PaymentStatus", "description": "Current lifecycle or operational status."}, "display": {"$ref": "#/components/schemas/PaymentDisplay", "description": "display value for payment response."}, "created_by": {"type": ["string", "null"], "format": "uuid", "description": "User id that created the resource."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "PaymentStatus": {"type": "string", "description": "Lifecycle status for a recorded payment.", "enum": ["COMPLETED", "REVERSED"]}, "PiiRevealRequest": {"type": "object", "description": "Request payload for pii reveal.", "required": ["resource_type", "resource_id", "fields", "reason", "action_token"], "properties": {"resource_type": {"type": "string", "description": "resource type value for pii reveal request."}, "resource_id": {"type": "string", "format": "uuid", "description": "UUID identifier for resource."}, "fields": {"type": "array", "items": {"type": "string"}, "description": "Field-level validation errors."}, "reason": {"type": "string", "description": "Operator-provided reason for a lifecycle action."}, "action_token": {"type": "string", "description": "action token value for pii reveal request."}}}, "PlatformRole": {"type": "string", "description": "Platform-level role used for internal operations access.", "enum": ["SUPER_ADMIN"]}, "PlatformUserResponse": {"type": "object", "description": "Response payload for platform user.", "required": ["id", "username", "status", "role", "mfa_enabled"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "username": {"type": "string", "description": "Unique username used for login and display."}, "email": {"type": ["string", "null"], "description": "Email address associated with the user or renter."}, "display_name": {"type": ["string", "null"], "description": "Human-readable display name."}, "status": {"type": "string", "description": "Current lifecycle or operational status."}, "role": {"type": "string", "description": "Role granted to the user in the relevant scope."}, "mfa_enabled": {"type": "boolean", "description": "mfa enabled value for platform user response."}}}, "PricingType": {"type": "string", "description": "Billing pricing mode for utility charges.", "enum": ["NONE", "FIXED", "METERED", "PER_OCCUPANT"]}, "PropertyListResponse": {"type": "object", "description": "List response payload containing property.", "required": ["properties"], "properties": {"properties": {"type": "array", "items": {"$ref": "#/components/schemas/PropertyResponse"}, "description": "Properties returned by the response."}}}, "PropertyResponse": {"type": "object", "description": "Response payload for property.", "required": ["id", "organization_id", "name", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "name": {"type": "string", "description": "Human-readable name for the resource."}, "address": {"type": ["string", "null"], "description": "Street address or address detail for the resource."}, "city": {"type": ["string", "null"], "description": "City portion of the address."}, "district": {"type": ["string", "null"], "description": "District portion of the address."}, "ward": {"type": ["string", "null"], "description": "Ward portion of the address."}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator."}, "archived_at": {"type": ["string", "null"], "format": "date-time", "description": "Timestamp when the resource was archived, if applicable."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "PropertyRoomProfitabilityAllocationReport": {"type": "object", "description": "Schema for property room profitability allocation report.", "required": ["organization_id", "date_from", "date_to", "allocation_method", "direct_revenue_cents", "direct_expense_cents", "property_level_expense_cents", "allocated_property_expense_cents", "allocated_expense_cents", "allocated_net_income_cents", "rows"], "properties": {"organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "date_from": {"type": "string", "format": "date", "description": "date from value for property room profitability allocation report."}, "date_to": {"type": "string", "format": "date", "description": "date to value for property room profitability allocation report."}, "allocation_method": {"$ref": "#/components/schemas/ExpenseAllocationMethod", "description": "allocation method value for property room profitability allocation report."}, "direct_revenue_cents": {"type": "integer", "format": "int64", "description": "direct revenue cents value for property room profitability allocation report."}, "direct_expense_cents": {"type": "integer", "format": "int64", "description": "direct expense cents value for property room profitability allocation report."}, "property_level_expense_cents": {"type": "integer", "format": "int64", "description": "property level expense cents value for property room profitability allocation report."}, "allocated_property_expense_cents": {"type": "integer", "format": "int64", "description": "allocated property expense cents value for property room profitability allocation report."}, "allocated_expense_cents": {"type": "integer", "format": "int64", "description": "allocated expense cents value for property room profitability allocation report."}, "allocated_net_income_cents": {"type": "integer", "format": "int64", "description": "allocated net income cents value for property room profitability allocation report."}, "rows": {"type": "array", "items": {"$ref": "#/components/schemas/PropertyRoomProfitabilityAllocationRow"}, "description": "Report rows returned by the response."}}}, "PropertyRoomProfitabilityAllocationRow": {"type": "object", "description": "Report row payload for property room profitability allocation.", "required": ["organization_id", "property_id", "room_id", "direct_revenue_cents", "direct_expense_cents", "allocation_basis_cents", "allocated_property_expense_cents", "allocated_expense_cents", "allocated_net_income_cents"], "properties": {"organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "direct_revenue_cents": {"type": "integer", "format": "int64", "description": "direct revenue cents value for property room profitability allocation row."}, "direct_expense_cents": {"type": "integer", "format": "int64", "description": "direct expense cents value for property room profitability allocation row."}, "allocation_basis_cents": {"type": "integer", "format": "int64", "description": "allocation basis cents value for property room profitability allocation row."}, "allocated_property_expense_cents": {"type": "integer", "format": "int64", "description": "allocated property expense cents value for property room profitability allocation row."}, "allocated_expense_cents": {"type": "integer", "format": "int64", "description": "allocated expense cents value for property room profitability allocation row."}, "allocated_net_income_cents": {"type": "integer", "format": "int64", "description": "allocated net income cents value for property room profitability allocation row."}}}, "PropertyRoomProfitabilityReport": {"type": "object", "description": "Schema for property room profitability report.", "required": ["organization_id", "date_from", "date_to", "revenue_cents", "expense_cents", "net_income_cents", "rows"], "properties": {"organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "date_from": {"type": "string", "format": "date", "description": "date from value for property room profitability report."}, "date_to": {"type": "string", "format": "date", "description": "date to value for property room profitability report."}, "revenue_cents": {"type": "integer", "format": "int64", "description": "revenue cents value for property room profitability report."}, "expense_cents": {"type": "integer", "format": "int64", "description": "expense cents value for property room profitability report."}, "net_income_cents": {"type": "integer", "format": "int64", "description": "net income cents value for property room profitability report."}, "rows": {"type": "array", "items": {"$ref": "#/components/schemas/PropertyRoomProfitabilityRow"}, "description": "Report rows returned by the response."}}}, "PropertyRoomProfitabilityRow": {"type": "object", "description": "Report row payload for property room profitability.", "required": ["organization_id", "revenue_cents", "expense_cents", "net_income_cents", "line_count"], "properties": {"organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for property."}, "room_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for room."}, "revenue_cents": {"type": "integer", "format": "int64", "description": "revenue cents value for property room profitability row."}, "expense_cents": {"type": "integer", "format": "int64", "description": "expense cents value for property room profitability row."}, "net_income_cents": {"type": "integer", "format": "int64", "description": "net income cents value for property room profitability row."}, "line_count": {"type": "integer", "description": "line count value for property room profitability row.", "minimum": 0}}}, "PublicInquiryAck": {"type": "object", "description": "Narrow confirmation returned to an anonymous inquiry submitter. Deliberately\nomits internal organization/property/room UUIDs (those are admin-only).", "required": ["id", "listing_slug", "property_name", "room_name", "status", "created_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "listing_slug": {"type": "string", "description": "listing slug value for public inquiry ack."}, "property_name": {"type": "string", "description": "Human-readable property name."}, "room_name": {"type": "string", "description": "Human-readable room name."}, "status": {"$ref": "#/components/schemas/ListingInquiryStatus", "description": "Current lifecycle or operational status."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}}}, "PublicListingDisplay": {"type": "object", "description": "Additive, locale-negotiated presentation for a public listing (ADR 0014,\nissue #16). Raw `amenities`/`city`/`district`/`ward`/`headline`/`description`\nare unchanged; `headline`/`description` are intentionally NOT translated.", "required": ["amenities", "location"], "properties": {"amenities": {"type": "array", "items": {"$ref": "#/components/schemas/DisplayLabel"}, "description": "One `{value,label}` per raw amenity, in the same order."}, "location": {"$ref": "#/components/schemas/ListingLocationDisplay", "description": "location value for public listing display."}}}, "PublicListingListResponse": {"type": "object", "description": "List response payload containing public listing.", "required": ["listings"], "properties": {"listings": {"type": "array", "items": {"$ref": "#/components/schemas/PublicListingResponse"}, "description": "listings value for public listing list response."}}}, "PublicListingResponse": {"type": "object", "description": "One public listing as the web FE consumes it. Money fields are decimal\nstrings (ADR 0008).", "required": ["id", "slug", "headline", "amenities", "organization_name", "property_name", "room_name", "base_rent", "default_deposit", "images", "updated_at", "display"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "slug": {"type": "string", "description": "URL-safe slug for the resource."}, "headline": {"type": "string", "description": "headline value for public listing response."}, "description": {"type": ["string", "null"], "description": "Human-readable description for the resource or line item."}, "amenities": {"type": "array", "items": {"type": "string"}, "description": "amenities value for public listing response."}, "contact_phone": {"type": ["string", "null"], "description": "contact phone value for public listing response."}, "zalo_url": {"type": ["string", "null"], "description": "zalo url value for public listing response."}, "available_date": {"type": ["string", "null"], "format": "date", "description": "available date value for public listing response."}, "min_lease_months": {"type": ["integer", "null"], "format": "int32", "description": "min lease months value for public listing response."}, "organization_name": {"type": "string", "description": "Human-readable organization name."}, "owner_name": {"type": ["string", "null"], "description": "Public-facing landlord name (the org's active OWNER display name), issue\n#32. `null` when the owner has not set a display name. Identity-safe: no\nemail/phone is exposed here."}, "property_name": {"type": "string", "description": "Human-readable property name."}, "property_address": {"type": ["string", "null"], "description": "property address value for public listing response."}, "city": {"type": ["string", "null"], "description": "City portion of the address."}, "district": {"type": ["string", "null"], "description": "District portion of the address."}, "ward": {"type": ["string", "null"], "description": "Ward portion of the address."}, "room_name": {"type": "string", "description": "Human-readable room name."}, "floor": {"type": ["string", "null"], "description": "Floor label or number where the room is located."}, "base_rent": {"type": "string", "description": "Default monthly rent amount for the room.", "example": "3500000"}, "default_deposit": {"type": "string", "description": "Default deposit amount used when creating leases.", "example": "3500000"}, "area_m2": {"type": ["number", "null"], "format": "double", "description": "Room area in square meters."}, "images": {"type": "array", "items": {"$ref": "#/components/schemas/ListingImageResponse"}, "description": "images value for public listing response."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}, "display": {"$ref": "#/components/schemas/PublicListingDisplay", "description": "Additive localized labels (ADR 0014, issue #16); raw fields above are\nunchanged across locales."}}}, "PushDeviceResponse": {"type": "object", "description": "Response payload for push device.", "required": ["id", "principal_type", "principal_id", "platform", "device_token", "created_at", "last_seen_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "principal_type": {"$ref": "#/components/schemas/PushPrincipalType", "description": "principal type value for push device response."}, "principal_id": {"type": "string", "format": "uuid", "description": "UUID identifier for principal."}, "platform": {"type": "string", "description": "platform value for push device response."}, "device_token": {"type": "string", "description": "device token value for push device response."}, "label": {"type": ["string", "null"], "description": "label value for push device response."}, "app_instance_id": {"type": ["string", "null"], "description": "UUID identifier for app instance."}, "app_version": {"type": ["string", "null"], "description": "app version value for push device response."}, "build_number": {"type": ["string", "null"], "description": "build number value for push device response."}, "os_version": {"type": ["string", "null"], "description": "os version value for push device response."}, "device_model": {"type": ["string", "null"], "description": "device model value for push device response."}, "environment": {"type": ["string", "null"], "description": "environment value for push device response."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "last_seen_at": {"type": "string", "format": "date-time", "description": "last seen at value for push device response."}}}, "PushPrincipalType": {"type": "string", "description": "Schema for push principal type.", "enum": ["landlord", "tenant"]}, "ReceivablesReportResponse": {"type": "object", "description": "Response payload for receivables report.", "required": ["period_from", "period_to", "total_receivable", "paid_amount", "unpaid_amount", "overdue_amount", "invoice_count", "series", "rows"], "properties": {"period": {"type": ["string", "null"], "description": "Billing period in YYYY-MM format."}, "period_from": {"type": "string", "description": "period from value for receivables report response."}, "period_to": {"type": "string", "description": "period to value for receivables report response."}, "property_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for property."}, "total_receivable": {"type": "string", "description": "Total receivable amount for the period."}, "paid_amount": {"type": "string", "description": "Amount already paid toward the invoice or period total."}, "unpaid_amount": {"type": "string", "description": "Amount still unpaid for the invoice or report row."}, "overdue_amount": {"type": "string", "description": "Total amount overdue for the period."}, "invoice_count": {"type": "integer", "format": "int64", "description": "Number of invoices included in the calculation."}, "series": {"type": "array", "items": {"$ref": "#/components/schemas/ReceivablesReportSeriesPoint"}, "description": "series value for receivables report response."}, "rows": {"type": "array", "items": {"$ref": "#/components/schemas/ReceivablesReportRow"}, "description": "Report rows returned by the response."}}}, "ReceivablesReportRow": {"type": "object", "description": "Report row payload for receivables report.", "required": ["property_id", "property_name", "invoice_count", "total_receivable", "paid_amount", "unpaid_amount", "overdue_amount"], "properties": {"property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "property_name": {"type": "string", "description": "Human-readable property name."}, "invoice_count": {"type": "integer", "format": "int64", "description": "Number of invoices included in the calculation."}, "total_receivable": {"type": "string", "description": "Total receivable amount for the period."}, "paid_amount": {"type": "string", "description": "Amount already paid toward the invoice or period total."}, "unpaid_amount": {"type": "string", "description": "Amount still unpaid for the invoice or report row."}, "overdue_amount": {"type": "string", "description": "Total amount overdue for the period."}}}, "ReceivablesReportSeriesPoint": {"type": "object", "description": "Schema for receivables report series point.", "required": ["period", "total_receivable", "paid_amount", "unpaid_amount", "overdue_amount", "invoice_count"], "properties": {"period": {"type": "string", "description": "Billing period in YYYY-MM format."}, "total_receivable": {"type": "string", "description": "Total receivable amount for the period."}, "paid_amount": {"type": "string", "description": "Amount already paid toward the invoice or period total."}, "unpaid_amount": {"type": "string", "description": "Amount still unpaid for the invoice or report row."}, "overdue_amount": {"type": "string", "description": "Total amount overdue for the period."}, "invoice_count": {"type": "integer", "format": "int64", "description": "Number of invoices included in the calculation."}}}, "RecordPaymentRequest": {"type": "object", "description": "Request payload for record payment.", "required": ["amount", "method", "payment_date"], "properties": {"amount": {"type": "string", "description": "Money as a decimal string (minor units internally); validated > 0 in the service.", "example": "1500000"}, "method": {"$ref": "#/components/schemas/PaymentMethod", "description": "Payment method used for the payment."}, "payment_date": {"type": "string", "format": "date", "description": "Date when the payment was received or recorded."}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "RefreshRequest": {"type": "object", "description": "Request payload for refresh.", "properties": {"refresh_token": {"type": ["string", "null"], "description": "Optional when the refresh token is supplied via the httpOnly cookie."}}}, "RefreshResponse": {"type": "object", "description": "Response payload for refresh.", "required": ["access_token", "refresh_token"], "properties": {"access_token": {"type": "string", "description": "Short-lived bearer token used in the Authorization header."}, "refresh_token": {"type": "string", "description": "Longer-lived token used only to refresh or revoke sessions."}}}, "RegisterPushDeviceRequest": {"type": "object", "description": "Request payload for register push device.", "required": ["platform", "device_token"], "properties": {"platform": {"type": "string", "description": "platform value for register push device request.", "maxLength": 20, "minLength": 1}, "device_token": {"type": "string", "description": "device token value for register push device request.", "maxLength": 4096, "minLength": 1}, "label": {"type": ["string", "null"], "description": "label value for register push device request.", "maxLength": 120}, "app_instance_id": {"type": ["string", "null"], "description": "UUID identifier for app instance.", "maxLength": 160}, "app_version": {"type": ["string", "null"], "description": "app version value for register push device request."}, "build_number": {"type": ["string", "null"], "description": "build number value for register push device request."}, "os_version": {"type": ["string", "null"], "description": "os version value for register push device request."}, "device_model": {"type": ["string", "null"], "description": "device model value for register push device request."}, "environment": {"type": ["string", "null"], "description": "environment value for register push device request."}}}, "RegisterRequest": {"type": "object", "description": "Request payload for register.", "required": ["username", "password", "organization_name"], "properties": {"username": {"type": "string", "description": "Unique username used for login and display.", "maxLength": 50, "minLength": 3}, "email": {"type": ["string", "null"], "format": "email", "description": "Email address associated with the user or renter."}, "password": {"type": "string", "description": "Plaintext password accepted only in authentication requests.", "minLength": 8}, "organization_name": {"type": "string", "description": "Human-readable organization name.", "maxLength": 100, "minLength": 2}, "display_name": {"type": ["string", "null"], "description": "Human-readable display name.", "maxLength": 100}}}, "RenterListResponse": {"type": "object", "description": "List response payload containing renter.", "required": ["renters"], "properties": {"renters": {"type": "array", "items": {"$ref": "#/components/schemas/RenterResponse"}, "description": "Renter profiles returned by the response."}}}, "RenterResponse": {"type": "object", "description": "Response payload for renter.", "required": ["id", "organization_id", "full_name", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "full_name": {"type": "string", "description": "Full legal or display name for the person."}, "phone": {"type": ["string", "null"], "description": "Phone number associated with the renter or user."}, "email": {"type": ["string", "null"], "description": "Email address associated with the user or renter."}, "identity_number": {"type": ["string", "null"], "description": "Government or landlord-recorded identity number for the renter."}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator."}, "archived_at": {"type": ["string", "null"], "format": "date-time", "description": "Timestamp when the resource was archived, if applicable."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "ResolveReviewItemRequest": {"type": "object", "description": "Request payload for resolve review item.", "required": ["reason"], "properties": {"reason": {"type": "string", "description": "Operator-provided reason for a lifecycle action.", "maxLength": 1000, "minLength": 1}}}, "RevenueReportResponse": {"type": "object", "description": "Response payload for revenue report.", "required": ["period_from", "period_to", "total_revenue", "payment_count", "series", "rows"], "properties": {"period": {"type": ["string", "null"], "description": "Billing period in YYYY-MM format."}, "period_from": {"type": "string", "description": "period from value for revenue report response."}, "period_to": {"type": "string", "description": "period to value for revenue report response."}, "property_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for property."}, "total_revenue": {"type": "string", "description": "Total revenue amount for the period."}, "payment_count": {"type": "integer", "format": "int64", "description": "Number of payments included in the calculation."}, "series": {"type": "array", "items": {"$ref": "#/components/schemas/RevenueReportSeriesPoint"}, "description": "series value for revenue report response."}, "rows": {"type": "array", "items": {"$ref": "#/components/schemas/RevenueReportRow"}, "description": "Report rows returned by the response."}}}, "RevenueReportRow": {"type": "object", "description": "Report row payload for revenue report.", "required": ["property_id", "property_name", "payment_count", "total_amount"], "properties": {"property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "property_name": {"type": "string", "description": "Human-readable property name."}, "payment_count": {"type": "integer", "format": "int64", "description": "Number of payments included in the calculation."}, "total_amount": {"type": "string", "description": "Total invoice, payment, or report amount."}}}, "RevenueReportSeriesPoint": {"type": "object", "description": "Schema for revenue report series point.", "required": ["period", "total_revenue", "payment_count"], "properties": {"period": {"type": "string", "description": "Billing period in YYYY-MM format."}, "total_revenue": {"type": "string", "description": "Total revenue amount for the period."}, "payment_count": {"type": "integer", "format": "int64", "description": "Number of payments included in the calculation."}}}, "ReversePaymentRequest": {"type": "object", "description": "Request payload for reverse payment.", "properties": {"note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "ReviewItemListQuery": {"type": "object", "description": "Schema for review item list query.", "properties": {"status": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/ReviewItemStatus"}], "description": "Current lifecycle or operational status."}, "property_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for property."}, "failure_reason": {"type": ["string", "null"], "description": "failure reason value for review item list query.", "maxLength": 80}, "received_from": {"type": ["string", "null"], "format": "date", "description": "received from value for review item list query."}, "received_to": {"type": ["string", "null"], "format": "date", "description": "received to value for review item list query."}, "limit": {"type": ["integer", "null"], "format": "int64", "description": "Maximum number of rows requested or returned.", "maximum": 500, "minimum": 1}, "offset": {"type": ["integer", "null"], "format": "int64", "description": "offset value for review item list query.", "minimum": 0}}}, "ReviewItemListResponse": {"type": "object", "description": "List response payload containing review item.", "required": ["review_items"], "properties": {"review_items": {"type": "array", "items": {"$ref": "#/components/schemas/ReviewItemResponse"}, "description": "review items value for review item list response."}}}, "ReviewItemResponse": {"type": "object", "description": "Response payload for review item.", "required": ["id", "provider", "status", "received_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "provider": {"type": "string", "description": "provider value for review item response."}, "provider_event_id": {"type": ["string", "null"], "description": "UUID identifier for provider event."}, "status": {"$ref": "#/components/schemas/ReviewItemStatus", "description": "Current lifecycle or operational status."}, "received_at": {"type": "string", "format": "date-time", "description": "received at value for review item response."}, "processed_at": {"type": ["string", "null"], "format": "date-time", "description": "processed at value for review item response."}, "transfer_type": {"type": ["string", "null"], "description": "transfer type value for review item response."}, "transfer_amount": {"type": ["string", "null"], "description": "transfer amount value for review item response."}, "payment_code": {"type": ["string", "null"], "description": "payment code value for review item response."}, "account_number": {"type": ["string", "null"], "description": "account number value for review item response."}, "property_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for property."}, "invoice_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for invoice."}, "payment_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for payment."}, "failure_reason": {"type": ["string", "null"], "description": "failure reason value for review item response."}, "reviewed_by": {"type": ["string", "null"], "format": "uuid", "description": "reviewed by value for review item response."}, "reviewed_at": {"type": ["string", "null"], "format": "date-time", "description": "reviewed at value for review item response."}, "review_note": {"type": ["string", "null"], "description": "review note value for review item response."}, "resolution_kind": {"type": ["string", "null"], "description": "resolution kind value for review item response."}}}, "ReviewItemStatus": {"type": "string", "description": "Schema for review item status.", "enum": ["NEEDS_REVIEW", "PROCESSED", "IGNORED", "RESOLVED"]}, "RoomImageResponse": {"type": "object", "description": "Response payload for room image.", "required": ["id", "image_url", "sort_order"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "media_asset_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for media asset."}, "image_url": {"type": "string", "description": "image url value for room image response."}, "alt_text": {"type": ["string", "null"], "description": "alt text value for room image response."}, "sort_order": {"type": "integer", "format": "int32", "description": "sort order value for room image response."}}}, "RoomListResponse": {"type": "object", "description": "List response payload containing room.", "required": ["rooms"], "properties": {"rooms": {"type": "array", "items": {"$ref": "#/components/schemas/RoomResponse"}, "description": "Rooms returned by the response."}}}, "RoomMeterReading": {"type": "object", "description": "Schema for room meter reading.", "required": ["room_id"], "properties": {"room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "electricity_previous": {"type": ["number", "null"], "format": "double", "description": "Previous electricity meter reading for the billing period.", "minimum": 0}, "electricity_current": {"type": ["number", "null"], "format": "double", "description": "Current electricity meter reading for the billing period.", "minimum": 0}, "water_previous": {"type": ["number", "null"], "format": "double", "description": "Previous water meter reading for the billing period.", "minimum": 0}, "water_current": {"type": ["number", "null"], "format": "double", "description": "Current water meter reading for the billing period.", "minimum": 0}}}, "RoomResponse": {"type": "object", "description": "Response payload for room.", "required": ["id", "organization_id", "property_id", "name", "status", "has_active_lease", "operational_status", "base_rent", "default_deposit", "created_at", "updated_at", "images"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "name": {"type": "string", "description": "Human-readable name for the resource."}, "floor": {"type": ["string", "null"], "description": "Floor label or number where the room is located."}, "status": {"$ref": "#/components/schemas/RoomStatus", "description": "Derived occupancy+operational status (ADR 0017). `HIDDEN`/`MAINTENANCE`\nreflect the operational override; otherwise `OCCUPIED` when the room has\nan active lease, else `VACANT`. Not directly settable as occupancy."}, "has_active_lease": {"type": "boolean", "description": "Truthful occupancy signal: whether an ACTIVE lease exists for the room,\nindependent of the operational override."}, "operational_status": {"$ref": "#/components/schemas/OperationalStatus", "description": "The stored, landlord-controlled operational state."}, "base_rent": {"type": "string", "description": "Default monthly rent amount for the room.", "example": "3000000"}, "default_deposit": {"type": "string", "description": "Default deposit amount used when creating leases.", "example": "3000000"}, "area_m2": {"type": ["number", "null"], "format": "double", "description": "Room area in square meters."}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator."}, "archived_at": {"type": ["string", "null"], "format": "date-time", "description": "Timestamp when the resource was archived, if applicable."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}, "images": {"type": "array", "items": {"$ref": "#/components/schemas/RoomImageResponse"}, "description": "images value for room response."}, "cover_image": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/RoomImageResponse"}], "description": "cover image value for room response."}, "meter_reading_status": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/MeterReadingStatus", "description": "Meter-reading completeness for the requested billing period. Null when\nno `period` query parameter was supplied."}], "description": "Derived meter-reading completeness for the requested billing period: NONE, PARTIAL, or COMPLETE. Null when no period query parameter was supplied."}, "meter_reading_id": {"type": ["string", "null"], "format": "uuid", "description": "Meter-reading row id for the requested billing period. Null when no\nperiod was supplied or no row exists for the room/period."}}}, "RoomStatus": {"type": "string", "description": "Occupancy+operational status as seen on the wire (ADR 0017). The four\nvalues are stable for clients, but `VACANT`/`OCCUPIED` are now *derived*\nfrom active-lease existence rather than stored; `HIDDEN`/`MAINTENANCE` are\nthe landlord-controlled operational override. Used for the room response\n`status`, the `?status=` list filter, and room-mutation requests.", "enum": ["VACANT", "OCCUPIED", "HIDDEN", "MAINTENANCE"]}, "RoomStatusHistoryListResponse": {"type": "object", "description": "List response payload containing room status history.", "required": ["history"], "properties": {"history": {"type": "array", "items": {"$ref": "#/components/schemas/RoomStatusHistoryResponse"}, "description": "Status history entries for the resource."}}}, "RoomStatusHistoryResponse": {"type": "object", "description": "Response payload for room status history.", "required": ["id", "organization_id", "room_id", "to_status", "changed_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "from_status": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/HistoryStatus"}], "description": "Previous lifecycle or room status."}, "to_status": {"$ref": "#/components/schemas/HistoryStatus", "description": "New lifecycle or room status."}, "reason": {"type": ["string", "null"], "description": "Operator-provided reason for a lifecycle action."}, "changed_by": {"type": ["string", "null"], "format": "uuid", "description": "User id that recorded the status transition."}, "changed_at": {"type": "string", "format": "date-time", "description": "Timestamp when the status transition was recorded."}}}, "SensitiveActionRequest": {"type": "object", "description": "Request payload for sensitive action.", "required": ["reason", "action_token"], "properties": {"reason": {"type": "string", "description": "Operator-provided reason for a lifecycle action."}, "action_token": {"type": "string", "description": "action token value for sensitive action request."}}}, "SepayWebhookAck": {"type": "object", "description": "Schema for sepay webhook ack.", "required": ["success"], "properties": {"success": {"type": "boolean", "description": "success value for sepay webhook ack."}}}, "SkippedRoom": {"type": "object", "description": "A room skipped by bulk generation because a non-cancelled invoice already\nexisted for the requested period.", "required": ["room_id", "existing_invoice_id"], "properties": {"room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "existing_invoice_id": {"type": "string", "format": "uuid", "description": "UUID identifier for existing invoice."}}}, "SocialProvider": {"type": "string", "description": "Schema for social provider.", "enum": ["google", "apple", "zalo"]}, "StartLeaseForRoomRequest": {"type": "object", "description": "Request payload for start lease for room.", "required": ["renter_id", "start_date", "monthly_rent", "deposit_amount"], "properties": {"renter_id": {"type": "string", "format": "uuid", "description": "UUID identifier for renter."}, "start_date": {"type": "string", "format": "date", "description": "Lease or report start date."}, "end_date": {"type": ["string", "null"], "format": "date", "description": "Lease or report end date."}, "monthly_rent": {"type": "string", "description": "Monthly rent amount for the lease.", "example": "3000000"}, "deposit_amount": {"type": "string", "description": "Deposit amount recorded for the lease.", "example": "3000000"}, "number_of_occupants": {"type": ["integer", "null"], "format": "int32", "description": "Number of occupants assigned to the room or lease.", "minimum": 1}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "StartLeaseRequest": {"type": "object", "description": "Request payload for start lease.", "required": ["room_id", "renter_id", "start_date", "monthly_rent", "deposit_amount"], "properties": {"room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "renter_id": {"type": "string", "format": "uuid", "description": "UUID identifier for renter."}, "start_date": {"type": "string", "format": "date", "description": "Lease or report start date."}, "end_date": {"type": ["string", "null"], "format": "date", "description": "Lease or report end date."}, "monthly_rent": {"type": "string", "description": "Monthly rent amount for the lease.", "example": "3000000"}, "deposit_amount": {"type": "string", "description": "Deposit amount recorded for the lease.", "example": "3000000"}, "number_of_occupants": {"type": ["integer", "null"], "format": "int32", "description": "Number of occupants assigned to the room or lease.", "minimum": 1}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "StepUpRequest": {"type": "object", "description": "Request payload for step up.", "required": ["password", "action_scope", "resource_type"], "properties": {"password": {"type": "string", "description": "Plaintext password accepted only in authentication requests."}, "mfa_code": {"type": ["string", "null"], "description": "mfa code value for step up request."}, "action_scope": {"type": "string", "description": "action scope value for step up request."}, "resource_type": {"type": "string", "description": "resource type value for step up request."}, "resource_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for resource."}}}, "StepUpResponse": {"type": "object", "description": "Response payload for step up.", "required": ["action_token", "expires_in"], "properties": {"action_token": {"type": "string", "description": "action token value for step up response."}, "expires_in": {"type": "integer", "format": "int64", "description": "expires in value for step up response."}}}, "SuccessBody": {"type": "object", "description": "Standard success envelope returned by JSON endpoints.", "required": ["data", "request_id"], "properties": {"data": {"description": "Endpoint-specific response data payload."}, "request_id": {"type": "string", "description": "Request correlation identifier for tracing and support."}, "meta": {"description": "Response metadata such as pagination counts."}}}, "TaxMethod": {"type": "string", "description": "How the organization files tax, which gates future legal e-invoice (H\u0110\u0110T)\nissuance (ADR 0018). Behavior-neutral today: `none` is the default and no\ntax logic keys off this field yet.", "enum": ["none", "ca_nhan", "ke_khai"]}, "TenantAccessAuditResponse": {"type": "object", "description": "Response payload for tenant access audit.", "required": ["events"], "properties": {"events": {"type": "array", "items": {"$ref": "#/components/schemas/TenantActivityResponse"}, "description": "events value for tenant access audit response."}}}, "TenantAccessResponse": {"type": "object", "description": "Response payload for tenant access.", "required": ["renter_id", "renter_name", "tenant_users", "invitations"], "properties": {"renter_id": {"type": "string", "format": "uuid", "description": "UUID identifier for renter."}, "renter_name": {"type": "string", "description": "Human-readable renter name."}, "tenant_users": {"type": "array", "items": {"$ref": "#/components/schemas/TenantRenterLinkResponse"}, "description": "tenant users value for tenant access response."}, "invitations": {"type": "array", "items": {"$ref": "#/components/schemas/TenantInvitationResponse"}, "description": "invitations value for tenant access response."}}}, "TenantAccountDeleteResponse": {"type": "object", "description": "Response payload for tenant account delete.", "required": ["deletion_requested"], "properties": {"deletion_requested": {"type": "boolean", "description": "deletion requested value for tenant account delete response."}}}, "TenantAccountExportResponse": {"type": "object", "description": "Response payload for tenant account export.", "required": ["requested", "tenant", "renter_links"], "properties": {"requested": {"type": "boolean", "description": "requested value for tenant account export response."}, "tenant": {"$ref": "#/components/schemas/TenantMeResponse", "description": "tenant value for tenant account export response."}, "renter_links": {"type": "array", "items": {"$ref": "#/components/schemas/TenantRenterLinkResponse"}, "description": "renter links value for tenant account export response."}}}, "TenantAckResponse": {"type": "object", "description": "Response payload for tenant ack.", "required": ["ok"], "properties": {"ok": {"type": "boolean", "description": "ok value for tenant ack response."}}}, "TenantActivityListResponse": {"type": "object", "description": "List response payload containing tenant activity.", "required": ["activity"], "properties": {"activity": {"type": "array", "items": {"$ref": "#/components/schemas/TenantActivityResponse"}, "description": "activity value for tenant activity list response."}}}, "TenantActivityResponse": {"type": "object", "description": "Response payload for tenant activity.", "required": ["id", "activity_type", "message", "data", "created_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for organization."}, "renter_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for renter."}, "activity_type": {"type": "string", "description": "activity type value for tenant activity response."}, "message": {"type": "string", "description": "Human-readable message safe to show in client logs or UI."}, "data": {"description": "Endpoint-specific response data payload."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}}}, "TenantAttachmentResponse": {"type": "object", "description": "Response payload for tenant attachment.", "required": ["id", "file_name", "file_url", "created_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "file_name": {"type": "string", "description": "file name value for tenant attachment response."}, "file_url": {"type": "string", "description": "file url value for tenant attachment response."}, "content_type": {"type": ["string", "null"], "description": "content type value for tenant attachment response."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}}}, "TenantAuthResponse": {"type": "object", "description": "Response payload for tenant auth.", "required": ["access_token", "refresh_token", "tenant"], "properties": {"access_token": {"type": "string", "description": "Short-lived bearer token used in the Authorization header."}, "refresh_token": {"type": "string", "description": "Longer-lived token used only to refresh or revoke sessions."}, "tenant": {"$ref": "#/components/schemas/TenantMeResponse", "description": "tenant value for tenant auth response."}}}, "TenantChangePasswordRequest": {"type": "object", "description": "Request payload for tenant change password.", "required": ["current_password", "new_password"], "properties": {"current_password": {"type": "string", "description": "current password value for tenant change password request.", "maxLength": 1024, "minLength": 1}, "new_password": {"type": "string", "description": "new password value for tenant change password request.", "maxLength": 1024, "minLength": 8}}}, "TenantClaimRequest": {"type": "object", "description": "Request payload for tenant claim.", "required": ["full_name"], "properties": {"organization_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for organization."}, "full_name": {"type": "string", "description": "Full legal or display name for the person.", "maxLength": 160, "minLength": 1}, "phone": {"type": ["string", "null"], "description": "Phone number associated with the renter or user.", "maxLength": 40}, "email": {"type": ["string", "null"], "format": "email", "description": "Email address associated with the user or renter."}, "identity_number": {"type": ["string", "null"], "description": "Government or landlord-recorded identity number for the renter.", "maxLength": 80}, "proof": {"description": "proof value for tenant claim request."}}}, "TenantClaimResponse": {"type": "object", "description": "Response payload for tenant claim.", "required": ["id", "status", "created_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "status": {"type": "string", "description": "Current lifecycle or operational status."}, "renter_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for renter."}, "organization_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for organization."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}}}, "TenantCommentResponse": {"type": "object", "description": "Response payload for tenant comment.", "required": ["id", "ticket_id", "actor_type", "body", "created_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "ticket_id": {"type": "string", "format": "uuid", "description": "UUID identifier for ticket."}, "actor_type": {"type": "string", "description": "actor type value for tenant comment response."}, "body": {"type": "string", "description": "body value for tenant comment response."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}}}, "TenantCreateAttachmentRequest": {"type": "object", "description": "Request payload for tenant create attachment.", "required": ["file_name", "file_url"], "properties": {"file_name": {"type": "string", "description": "file name value for tenant create attachment request.", "maxLength": 255, "minLength": 1}, "file_url": {"type": "string", "description": "file url value for tenant create attachment request.", "maxLength": 1000, "minLength": 1}, "content_type": {"type": ["string", "null"], "description": "content type value for tenant create attachment request.", "maxLength": 120}}}, "TenantCreateCommentRequest": {"type": "object", "description": "Request payload for tenant create comment.", "required": ["body"], "properties": {"body": {"type": "string", "description": "body value for tenant create comment request.", "maxLength": 2000, "minLength": 1}}}, "TenantCreateMaintenanceTicketRequest": {"type": "object", "description": "Request payload for tenant create maintenance ticket.", "required": ["title", "description", "priority"], "properties": {"room_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for room."}, "invoice_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for invoice."}, "title": {"type": "string", "description": "title value for tenant create maintenance ticket request.", "maxLength": 160, "minLength": 1}, "description": {"type": "string", "description": "Human-readable description for the resource or line item.", "maxLength": 2000, "minLength": 1}, "priority": {"type": "string", "description": "priority value for tenant create maintenance ticket request.", "maxLength": 6, "minLength": 3, "pattern": "^(LOW|NORMAL|HIGH|URGENT)$"}, "reported_by_contact": {"type": ["string", "null"], "description": "reported by contact value for tenant create maintenance ticket request.", "maxLength": 160}}}, "TenantCreateMessageRequest": {"type": "object", "description": "Request payload for tenant create message.", "required": ["body"], "properties": {"body": {"type": "string", "description": "body value for tenant create message request.", "maxLength": 2000, "minLength": 1}}}, "TenantCreateThreadRequest": {"type": "object", "description": "Request payload for tenant create thread.", "required": ["subject", "message"], "properties": {"renter_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for renter."}, "subject": {"type": "string", "description": "subject value for tenant create thread request.", "maxLength": 160, "minLength": 1}, "message": {"type": "string", "description": "Human-readable message safe to show in client logs or UI.", "maxLength": 2000, "minLength": 1}}}, "TenantDeviceResponse": {"type": "object", "description": "Response payload for tenant device.", "required": ["id", "platform", "device_token", "created_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "platform": {"type": "string", "description": "platform value for tenant device response."}, "device_token": {"type": "string", "description": "device token value for tenant device response."}, "label": {"type": ["string", "null"], "description": "label value for tenant device response."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}}}, "TenantDocumentDownloadResponse": {"type": "object", "description": "Response payload for tenant document download.", "required": ["document_id"], "properties": {"document_id": {"type": "string", "format": "uuid", "description": "UUID identifier for document."}, "file_url": {"type": ["string", "null"], "description": "file url value for tenant document download response."}, "content": {"type": ["string", "null"], "description": "content value for tenant document download response."}}}, "TenantDocumentListResponse": {"type": "object", "description": "List response payload containing tenant document.", "required": ["documents"], "properties": {"documents": {"type": "array", "items": {"$ref": "#/components/schemas/TenantDocumentResponse"}, "description": "documents value for tenant document list response."}}}, "TenantDocumentResponse": {"type": "object", "description": "Response payload for tenant document.", "required": ["id", "organization_id", "renter_id", "title", "document_type", "created_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "renter_id": {"type": "string", "format": "uuid", "description": "UUID identifier for renter."}, "invoice_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for invoice."}, "lease_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for lease."}, "title": {"type": "string", "description": "title value for tenant document response."}, "document_type": {"type": "string", "description": "document type value for tenant document response."}, "file_url": {"type": ["string", "null"], "description": "file url value for tenant document response."}, "content": {"type": ["string", "null"], "description": "content value for tenant document response."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}}}, "TenantForgotPasswordRequest": {"type": "object", "description": "Request payload for tenant forgot password.", "required": ["email"], "properties": {"email": {"type": "string", "format": "email", "description": "Email address associated with the user or renter.", "maxLength": 254}}}, "TenantHomeResponse": {"type": "object", "description": "Response payload for tenant home.", "required": ["active_links", "unpaid_balance", "open_ticket_count", "unread_notification_count"], "properties": {"active_links": {"type": "array", "items": {"$ref": "#/components/schemas/TenantRenterLinkResponse"}, "description": "active links value for tenant home response."}, "current_residence": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/TenantResidenceResponse"}], "description": "current residence value for tenant home response."}, "latest_invoice": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/TenantInvoiceSummaryResponse"}], "description": "latest invoice value for tenant home response."}, "unpaid_balance": {"type": "string", "description": "unpaid balance value for tenant home response."}, "open_ticket_count": {"type": "integer", "format": "int64", "description": "open ticket count value for tenant home response."}, "unread_notification_count": {"type": "integer", "format": "int64", "description": "unread notification count value for tenant home response."}}}, "TenantHouseholdResponse": {"type": "object", "description": "Response payload for tenant household.", "required": ["household"], "properties": {"household": {"description": "household value for tenant household response."}}}, "TenantInvitationPreviewResponse": {"type": "object", "description": "Response payload for tenant invitation preview.", "required": ["organization_id", "organization_name", "renter_id", "renter_name", "status", "expires_at"], "properties": {"organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "organization_name": {"type": "string", "description": "Human-readable organization name."}, "renter_id": {"type": "string", "format": "uuid", "description": "UUID identifier for renter."}, "renter_name": {"type": "string", "description": "Human-readable renter name."}, "status": {"type": "string", "description": "Current lifecycle or operational status."}, "expires_at": {"type": "string", "format": "date-time", "description": "expires at value for tenant invitation preview response."}}}, "TenantInvitationResponse": {"type": "object", "description": "Response payload for tenant invitation.", "required": ["id", "organization_id", "renter_id", "status", "expires_at", "created_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "renter_id": {"type": "string", "format": "uuid", "description": "UUID identifier for renter."}, "token": {"type": ["string", "null"], "description": "token value for tenant invitation response."}, "status": {"type": "string", "description": "Current lifecycle or operational status."}, "invitee_email": {"type": ["string", "null"], "description": "invitee email value for tenant invitation response."}, "invitee_phone": {"type": ["string", "null"], "description": "invitee phone value for tenant invitation response."}, "expires_at": {"type": "string", "format": "date-time", "description": "expires at value for tenant invitation response."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}}}, "TenantInvoiceDetailResponse": {"allOf": [{"$ref": "#/components/schemas/TenantInvoiceSummaryResponse", "description": "Composed schema segment for this value."}, {"type": "object", "description": "Composed schema segment for this value.", "required": ["lines"], "properties": {"lines": {"type": "array", "items": {"$ref": "#/components/schemas/TenantInvoiceLineResponse"}}}}], "description": "Response payload for tenant invoice detail."}, "TenantInvoiceDisplay": {"type": "object", "description": "Localized labels for the tenant-portal invoice header fields (ADR 0014).\nAdditive: the raw `status` field on the parent is unchanged.", "required": ["status"], "properties": {"status": {"$ref": "#/components/schemas/DisplayLabel", "description": "Current lifecycle or operational status."}}}, "TenantInvoiceFormOptions": {"type": "object", "description": "API-owned dropdown options for the public maintenance-request form so the\nfrontend does not hardcode the priority list/labels (ADR 0014).", "required": ["maintenance_priorities"], "properties": {"maintenance_priorities": {"type": "array", "items": {"$ref": "#/components/schemas/DisplayLabel"}, "description": "maintenance priorities value for tenant invoice form options."}}}, "TenantInvoiceLineDisplay": {"type": "object", "description": "Localized labels for a tenant-portal invoice line (ADR 0014).", "required": ["line_type"], "properties": {"line_type": {"$ref": "#/components/schemas/DisplayLabel", "description": "Invoice line classification used for totals."}}}, "TenantInvoiceLineResponse": {"type": "object", "description": "Response payload for tenant invoice line.", "required": ["description", "line_type", "quantity", "unit_price", "amount", "display"], "properties": {"description": {"type": "string", "description": "Human-readable description for the resource or line item."}, "line_type": {"type": "string", "description": "Invoice line classification used for totals."}, "quantity": {"type": "string", "description": "Quantity multiplier used for invoice line calculations."}, "unit_price": {"type": "string", "description": "Unit price used for invoice line calculations."}, "amount": {"type": "string", "description": "Money amount represented in the API currency unit."}, "display": {"$ref": "#/components/schemas/TenantInvoiceLineDisplay", "description": "display value for tenant invoice line response."}}}, "TenantInvoiceLinkResponse": {"type": "object", "description": "Response payload for tenant invoice link.", "required": ["invoice_id", "public_token", "public_url_path"], "properties": {"invoice_id": {"type": "string", "format": "uuid", "description": "UUID identifier for invoice."}, "public_token": {"type": "string", "description": "public token value for tenant invoice link response."}, "public_url_path": {"type": "string", "description": "public url path value for tenant invoice link response."}}}, "TenantInvoiceListResponse": {"type": "object", "description": "List response payload containing tenant invoice.", "required": ["invoices"], "properties": {"invoices": {"type": "array", "items": {"$ref": "#/components/schemas/TenantInvoiceSummaryResponse"}, "description": "Invoices returned by the response."}}}, "TenantInvoiceQuery": {"type": "object", "description": "Schema for tenant invoice query.", "properties": {"status": {"type": ["string", "null"], "description": "Current lifecycle or operational status."}, "period": {"type": ["string", "null"], "description": "Billing period in YYYY-MM format.", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}}, "TenantInvoiceSummaryResponse": {"type": "object", "description": "Response payload for tenant invoice summary.", "required": ["id", "organization_id", "property_id", "room_id", "renter_id", "period", "invoice_number", "status", "effective_status", "due_date", "total_amount", "paid_amount", "balance_amount", "payment_reference", "payment_code"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "renter_id": {"type": "string", "format": "uuid", "description": "UUID identifier for renter."}, "period": {"type": "string", "description": "Billing period in YYYY-MM format."}, "invoice_number": {"type": "string", "description": "Human-readable invoice number."}, "status": {"type": "string", "description": "Persisted lifecycle/storage status."}, "effective_status": {"type": "string", "description": "Backend-owned current invoice state for UI rendering. Past-due issued or\npartially paid invoices with remaining balance are represented as OVERDUE."}, "issue_date": {"type": ["string", "null"], "format": "date", "description": "Date when the invoice was issued."}, "due_date": {"type": "string", "format": "date", "description": "Date when the invoice is due."}, "total_amount": {"type": "string", "description": "Total invoice, payment, or report amount."}, "paid_amount": {"type": "string", "description": "Amount already paid toward the invoice or period total."}, "balance_amount": {"type": "string", "description": "balance amount value for tenant invoice summary response."}, "payment_reference": {"type": "string", "description": "External or manual reference for payment reconciliation."}, "payment_code": {"type": "string", "description": "payment code value for tenant invoice summary response."}}}, "TenantLeaseListResponse": {"type": "object", "description": "List response payload containing tenant lease.", "required": ["leases"], "properties": {"leases": {"type": "array", "items": {"$ref": "#/components/schemas/TenantLeaseResponse"}, "description": "Leases returned by the response."}}}, "TenantLeaseResponse": {"type": "object", "description": "Response payload for tenant lease.", "required": ["id", "organization_id", "property_id", "room_id", "renter_id", "status", "start_date", "monthly_rent", "deposit_amount", "number_of_occupants", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "renter_id": {"type": "string", "format": "uuid", "description": "UUID identifier for renter."}, "status": {"type": "string", "description": "Current lifecycle or operational status."}, "start_date": {"type": "string", "format": "date", "description": "Lease or report start date."}, "end_date": {"type": ["string", "null"], "format": "date", "description": "Lease or report end date."}, "monthly_rent": {"type": "string", "description": "Monthly rent amount for the lease."}, "deposit_amount": {"type": "string", "description": "Deposit amount recorded for the lease."}, "number_of_occupants": {"type": "integer", "format": "int32", "description": "Number of occupants assigned to the room or lease."}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "TenantListMeta": {"type": "object", "description": "Schema for tenant list meta.", "required": ["count", "limit"], "properties": {"count": {"type": "integer", "description": "Number of rows represented by the response metadata.", "minimum": 0}, "limit": {"type": "integer", "description": "Maximum number of rows requested or returned.", "example": 100, "minimum": 0}}}, "TenantLoginRequest": {"type": "object", "description": "Request payload for tenant login.", "required": ["email", "password"], "properties": {"email": {"type": "string", "format": "email", "description": "Email address associated with the user or renter.", "maxLength": 254}, "password": {"type": "string", "description": "Plaintext password accepted only in authentication requests.", "maxLength": 1024, "minLength": 1}}}, "TenantLogoutRequest": {"type": "object", "description": "Request payload for tenant logout.", "properties": {"refresh_token": {"type": ["string", "null"], "description": "Longer-lived token used only to refresh or revoke sessions.", "maxLength": 512, "minLength": 1}}}, "TenantLogoutResponse": {"type": "object", "description": "Response payload for tenant logout.", "required": ["logged_out"], "properties": {"logged_out": {"type": "boolean", "description": "Whether logout completed successfully."}}}, "TenantMaintenanceTicketListResponse": {"type": "object", "description": "List response payload containing tenant maintenance ticket.", "required": ["tickets"], "properties": {"tickets": {"type": "array", "items": {"$ref": "#/components/schemas/TenantMaintenanceTicketResponse"}, "description": "tickets value for tenant maintenance ticket list response."}}}, "TenantMaintenanceTicketRequest": {"type": "object", "description": "Request payload for tenant maintenance ticket.", "required": ["title", "description"], "properties": {"title": {"type": "string", "description": "title value for tenant maintenance ticket request.", "maxLength": 160, "minLength": 1}, "description": {"type": "string", "description": "Human-readable description for the resource or line item.", "maxLength": 2000, "minLength": 1}, "priority": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/MaintenanceTicketPriority"}], "description": "priority value for tenant maintenance ticket request."}, "reported_by_name": {"type": ["string", "null"], "description": "reported by name value for tenant maintenance ticket request.", "maxLength": 160}, "reported_by_contact": {"type": ["string", "null"], "description": "reported by contact value for tenant maintenance ticket request.", "maxLength": 160}}}, "TenantMaintenanceTicketResponse": {"type": "object", "description": "Response payload for tenant maintenance ticket.", "required": ["ticket"], "properties": {"ticket": {"$ref": "#/components/schemas/MaintenanceTicketResponse", "description": "ticket value for tenant maintenance ticket response."}}}, "TenantMeResponse": {"type": "object", "description": "Response payload for tenant me.", "required": ["id", "email", "display_name", "status", "locale", "timezone", "created_at", "updated_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "email": {"type": "string", "description": "Email address associated with the user or renter."}, "phone": {"type": ["string", "null"], "description": "Phone number associated with the renter or user."}, "display_name": {"type": "string", "description": "Human-readable display name."}, "status": {"type": "string", "description": "Current lifecycle or operational status."}, "locale": {"type": "string", "description": "locale value for tenant me response."}, "timezone": {"type": "string", "description": "timezone value for tenant me response."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "TenantMeterReadingListResponse": {"type": "object", "description": "List response payload containing tenant meter reading.", "required": ["meter_readings"], "properties": {"meter_readings": {"type": "array", "items": {"$ref": "#/components/schemas/TenantMeterReadingResponse"}, "description": "Meter readings returned by the response."}}}, "TenantMeterReadingResponse": {"type": "object", "description": "Response payload for tenant meter reading.", "required": ["id", "organization_id", "property_id", "room_id", "period", "recorded_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "period": {"type": "string", "description": "Billing period in YYYY-MM format."}, "electricity_previous": {"type": ["number", "null"], "format": "double", "description": "Previous electricity meter reading for the billing period."}, "electricity_current": {"type": ["number", "null"], "format": "double", "description": "Current electricity meter reading for the billing period."}, "water_previous": {"type": ["number", "null"], "format": "double", "description": "Previous water meter reading for the billing period."}, "water_current": {"type": ["number", "null"], "format": "double", "description": "Current water meter reading for the billing period."}, "recorded_at": {"type": "string", "format": "date-time", "description": "Timestamp when the event or payment was recorded."}}}, "TenantNotificationListResponse": {"type": "object", "description": "List response payload containing tenant notification.", "required": ["notifications"], "properties": {"notifications": {"type": "array", "items": {"$ref": "#/components/schemas/TenantNotificationResponse"}, "description": "notifications value for tenant notification list response."}}}, "TenantNotificationPreferencesResponse": {"type": "object", "description": "Response payload for tenant notification preferences.", "required": ["email_enabled", "push_enabled", "invoice_updates", "maintenance_updates", "message_updates", "updated_at"], "properties": {"email_enabled": {"type": "boolean", "description": "email enabled value for tenant notification preferences response."}, "push_enabled": {"type": "boolean", "description": "push enabled value for tenant notification preferences response."}, "invoice_updates": {"type": "boolean", "description": "invoice updates value for tenant notification preferences response."}, "maintenance_updates": {"type": "boolean", "description": "maintenance updates value for tenant notification preferences response."}, "message_updates": {"type": "boolean", "description": "message updates value for tenant notification preferences response."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}}}, "TenantNotificationResponse": {"type": "object", "description": "Response payload for tenant notification.", "required": ["id", "notification_type", "title", "body", "data", "created_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for organization."}, "renter_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for renter."}, "notification_type": {"type": "string", "description": "notification type value for tenant notification response."}, "title": {"type": "string", "description": "title value for tenant notification response."}, "body": {"type": "string", "description": "body value for tenant notification response."}, "data": {"description": "Endpoint-specific response data payload."}, "read_at": {"type": ["string", "null"], "format": "date-time", "description": "read at value for tenant notification response."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}}}, "TenantPasswordResetStartResponse": {"type": "object", "description": "Response payload for tenant password reset start.", "required": ["accepted"], "properties": {"accepted": {"type": "boolean", "description": "accepted value for tenant password reset start response."}, "reset_token": {"type": ["string", "null"], "description": "reset token value for tenant password reset start response."}}}, "TenantPaymentConfirmationListResponse": {"type": "object", "description": "List response payload containing tenant payment confirmation.", "required": ["payment_confirmations"], "properties": {"payment_confirmations": {"type": "array", "items": {"$ref": "#/components/schemas/TenantPaymentConfirmationResponse"}, "description": "payment confirmations value for tenant payment confirmation list response."}}}, "TenantPaymentConfirmationResponse": {"type": "object", "description": "Response payload for tenant payment confirmation.", "required": ["id", "invoice_id", "amount", "status", "created_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "invoice_id": {"type": "string", "format": "uuid", "description": "UUID identifier for invoice."}, "amount": {"type": "string", "description": "Money amount represented in the API currency unit."}, "paid_at": {"type": ["string", "null"], "format": "date-time", "description": "paid at value for tenant payment confirmation response."}, "transfer_reference": {"type": ["string", "null"], "description": "transfer reference value for tenant payment confirmation response."}, "receipt_url": {"type": ["string", "null"], "description": "receipt url value for tenant payment confirmation response."}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator."}, "status": {"type": "string", "description": "Current lifecycle or operational status."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}}}, "TenantPaymentDisplay": {"type": "object", "description": "Localized labels for a tenant-portal payment row (ADR 0014).", "required": ["method", "status"], "properties": {"method": {"$ref": "#/components/schemas/DisplayLabel", "description": "Payment method used for the payment."}, "status": {"$ref": "#/components/schemas/DisplayLabel", "description": "Current lifecycle or operational status."}}}, "TenantPaymentInstructionResponse": {"type": "object", "description": "Response payload for tenant payment instruction.", "required": ["invoice_id", "payment_reference", "payment_code", "transfer_content", "balance_amount"], "properties": {"invoice_id": {"type": "string", "format": "uuid", "description": "UUID identifier for invoice."}, "payment_reference": {"type": "string", "description": "External or manual reference for payment reconciliation."}, "payment_code": {"type": "string", "description": "payment code value for tenant payment instruction response."}, "transfer_content": {"type": "string", "description": "Server-rendered transfer content used for payment instructions and QR generation."}, "balance_amount": {"type": "string", "description": "balance amount value for tenant payment instruction response."}, "bank_name": {"type": ["string", "null"], "description": "Bank name for the payment account."}, "sepay_bank_code": {"type": ["string", "null"], "description": "sepay bank code value for tenant payment instruction response."}, "bank_account_number": {"type": ["string", "null"], "description": "Bank account number used for tenant transfers."}, "bank_account_holder": {"type": ["string", "null"], "description": "Name of the bank account holder for transfers."}}}, "TenantPaymentListResponse": {"type": "object", "description": "List response payload containing tenant payment.", "required": ["payments"], "properties": {"payments": {"type": "array", "items": {"$ref": "#/components/schemas/TenantPaymentResponse"}, "description": "Payments returned by the response."}}}, "TenantPaymentResponse": {"type": "object", "description": "Response payload for tenant payment.", "required": ["payment_date", "amount", "method", "status", "created_at", "display"], "properties": {"payment_date": {"type": "string", "format": "date", "description": "Date when the payment was received or recorded."}, "amount": {"type": "string", "description": "Money amount represented in the API currency unit."}, "method": {"type": "string", "description": "Payment method used for the payment."}, "status": {"type": "string", "description": "Current lifecycle or operational status."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "display": {"$ref": "#/components/schemas/TenantPaymentDisplay", "description": "display value for tenant payment response."}}}, "TenantPeriodQuery": {"type": "object", "description": "Schema for tenant period query.", "properties": {"period": {"type": ["string", "null"], "description": "Billing period in YYYY-MM format.", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}}}, "TenantPortalInvoiceResponse": {"type": "object", "description": "Response payload for tenant portal invoice.", "required": ["invoice_id", "invoice_number", "period", "status", "display", "due_date", "total_amount", "paid_amount", "balance_amount", "payment_reference", "payment_code", "transfer_content", "organization_name", "property_name", "room_name", "renter_name", "lines", "payments", "form_options"], "properties": {"invoice_id": {"type": "string", "format": "uuid", "description": "UUID identifier for invoice."}, "invoice_number": {"type": "string", "description": "Human-readable invoice number."}, "period": {"type": "string", "description": "Billing period in YYYY-MM format."}, "status": {"type": "string", "description": "Current lifecycle or operational status."}, "display": {"$ref": "#/components/schemas/TenantInvoiceDisplay", "description": "display value for tenant portal invoice response."}, "due_date": {"type": "string", "format": "date", "description": "Date when the invoice is due."}, "total_amount": {"type": "string", "description": "Total invoice, payment, or report amount."}, "paid_amount": {"type": "string", "description": "Amount already paid toward the invoice or period total."}, "balance_amount": {"type": "string", "description": "balance amount value for tenant portal invoice response."}, "payment_reference": {"type": "string", "description": "External or manual reference for payment reconciliation."}, "payment_code": {"type": "string", "description": "payment code value for tenant portal invoice response."}, "transfer_content": {"type": "string", "description": "Server-rendered transfer content used for payment instructions and QR generation."}, "payment_qr_image_url": {"type": ["string", "null"], "description": "payment qr image url value for tenant portal invoice response."}, "payment_account_bank_name": {"type": ["string", "null"], "description": "payment account bank name value for tenant portal invoice response."}, "payment_account_sepay_bank_code": {"type": ["string", "null"], "description": "payment account sepay bank code value for tenant portal invoice response."}, "payment_account_number": {"type": ["string", "null"], "description": "payment account number value for tenant portal invoice response."}, "payment_account_holder": {"type": ["string", "null"], "description": "payment account holder value for tenant portal invoice response."}, "organization_name": {"type": "string", "description": "Human-readable organization name."}, "property_name": {"type": "string", "description": "Human-readable property name."}, "room_name": {"type": "string", "description": "Human-readable room name."}, "renter_name": {"type": "string", "description": "Human-readable renter name."}, "lines": {"type": "array", "items": {"$ref": "#/components/schemas/TenantInvoiceLineResponse"}, "description": "Invoice line items included in the invoice."}, "payments": {"type": "array", "items": {"$ref": "#/components/schemas/TenantPaymentResponse"}, "description": "Payments returned by the response."}, "form_options": {"$ref": "#/components/schemas/TenantInvoiceFormOptions", "description": "form options value for tenant portal invoice response."}}}, "TenantProfileResponse": {"type": "object", "description": "Response payload for tenant profile.", "required": ["tenant", "profile"], "properties": {"tenant": {"$ref": "#/components/schemas/TenantMeResponse", "description": "tenant value for tenant profile response."}, "profile": {"description": "profile value for tenant profile response."}}}, "TenantRefreshRequest": {"type": "object", "description": "Request payload for tenant refresh.", "properties": {"refresh_token": {"type": ["string", "null"], "description": "Longer-lived token used only to refresh or revoke sessions.", "maxLength": 512, "minLength": 1}}}, "TenantRefreshResponse": {"type": "object", "description": "Response payload for tenant refresh.", "required": ["access_token", "refresh_token"], "properties": {"access_token": {"type": "string", "description": "Short-lived bearer token used in the Authorization header."}, "refresh_token": {"type": "string", "description": "Longer-lived token used only to refresh or revoke sessions."}}}, "TenantRegisterDeviceRequest": {"type": "object", "description": "Request payload for tenant register device.", "required": ["platform", "device_token"], "properties": {"platform": {"type": "string", "description": "platform value for tenant register device request.", "maxLength": 20, "minLength": 1}, "device_token": {"type": "string", "description": "device token value for tenant register device request.", "maxLength": 4096, "minLength": 1}, "label": {"type": ["string", "null"], "description": "label value for tenant register device request.", "maxLength": 120}}}, "TenantRegisterRequest": {"type": "object", "description": "Request payload for tenant register.", "required": ["email", "password", "display_name"], "properties": {"email": {"type": "string", "format": "email", "description": "Email address associated with the user or renter.", "maxLength": 254}, "password": {"type": "string", "description": "Plaintext password accepted only in authentication requests.", "maxLength": 1024, "minLength": 8}, "display_name": {"type": "string", "description": "Human-readable display name.", "maxLength": 160, "minLength": 1}, "phone": {"type": ["string", "null"], "description": "Phone number associated with the renter or user.", "maxLength": 40}}}, "TenantRenterLinkListResponse": {"type": "object", "description": "List response payload containing tenant renter link.", "required": ["renter_links"], "properties": {"renter_links": {"type": "array", "items": {"$ref": "#/components/schemas/TenantRenterLinkResponse"}, "description": "renter links value for tenant renter link list response."}}}, "TenantRenterLinkResponse": {"type": "object", "description": "Response payload for tenant renter link.", "required": ["id", "organization_id", "organization_name", "renter_id", "renter_name", "status", "source", "created_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "organization_name": {"type": "string", "description": "Human-readable organization name."}, "renter_id": {"type": "string", "format": "uuid", "description": "UUID identifier for renter."}, "renter_name": {"type": "string", "description": "Human-readable renter name."}, "status": {"type": "string", "description": "Current lifecycle or operational status."}, "source": {"type": "string", "description": "External or internal source that supplied the response data."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}}}, "TenantResetPasswordRequest": {"type": "object", "description": "Request payload for tenant reset password.", "required": ["reset_token", "new_password"], "properties": {"reset_token": {"type": "string", "description": "reset token value for tenant reset password request.", "maxLength": 512, "minLength": 1}, "new_password": {"type": "string", "description": "new password value for tenant reset password request.", "maxLength": 1024, "minLength": 8}}}, "TenantResidenceListResponse": {"type": "object", "description": "List response payload containing tenant residence.", "required": ["residences"], "properties": {"residences": {"type": "array", "items": {"$ref": "#/components/schemas/TenantResidenceResponse"}, "description": "residences value for tenant residence list response."}}}, "TenantResidenceResponse": {"type": "object", "description": "Response payload for tenant residence.", "required": ["residence_id", "organization_id", "property_id", "property_name", "room_id", "room_name", "renter_id", "renter_name", "lease_id", "lease_status", "start_date"], "properties": {"residence_id": {"type": "string", "format": "uuid", "description": "UUID identifier for residence."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "property_id": {"type": "string", "format": "uuid", "description": "UUID identifier for property."}, "property_name": {"type": "string", "description": "Human-readable property name."}, "room_id": {"type": "string", "format": "uuid", "description": "UUID identifier for room."}, "room_name": {"type": "string", "description": "Human-readable room name."}, "renter_id": {"type": "string", "format": "uuid", "description": "UUID identifier for renter."}, "renter_name": {"type": "string", "description": "Human-readable renter name."}, "lease_id": {"type": "string", "format": "uuid", "description": "UUID identifier for lease."}, "lease_status": {"type": "string", "description": "lease status value for tenant residence response."}, "start_date": {"type": "string", "format": "date", "description": "Lease or report start date."}, "end_date": {"type": ["string", "null"], "format": "date", "description": "Lease or report end date."}}}, "TenantSessionListResponse": {"type": "object", "description": "List response payload containing tenant session.", "required": ["sessions"], "properties": {"sessions": {"type": "array", "items": {"$ref": "#/components/schemas/TenantSessionResponse"}, "description": "sessions value for tenant session list response."}}}, "TenantSessionResponse": {"type": "object", "description": "Response payload for tenant session.", "required": ["id", "expires_at", "created_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "expires_at": {"type": "string", "format": "date-time", "description": "expires at value for tenant session response."}, "revoked_at": {"type": ["string", "null"], "format": "date-time", "description": "revoked at value for tenant session response."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "last_used_at": {"type": ["string", "null"], "format": "date-time", "description": "last used at value for tenant session response."}}}, "TenantThreadListResponse": {"type": "object", "description": "List response payload containing tenant thread.", "required": ["threads"], "properties": {"threads": {"type": "array", "items": {"$ref": "#/components/schemas/TenantThreadResponse"}, "description": "threads value for tenant thread list response."}}}, "TenantThreadMessageResponse": {"type": "object", "description": "Response payload for tenant thread message.", "required": ["id", "actor_type", "body", "created_at"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "actor_type": {"type": "string", "description": "actor type value for tenant thread message response."}, "body": {"type": "string", "description": "body value for tenant thread message response."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}}}, "TenantThreadResponse": {"type": "object", "description": "Response payload for tenant thread.", "required": ["id", "organization_id", "renter_id", "subject", "status", "created_at", "updated_at", "messages"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "organization_id": {"type": "string", "format": "uuid", "description": "UUID identifier for organization."}, "renter_id": {"type": "string", "format": "uuid", "description": "UUID identifier for renter."}, "subject": {"type": "string", "description": "subject value for tenant thread response."}, "status": {"type": "string", "description": "Current lifecycle or operational status."}, "created_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was created."}, "updated_at": {"type": "string", "format": "date-time", "description": "Timestamp when the resource was last updated."}, "messages": {"type": "array", "items": {"$ref": "#/components/schemas/TenantThreadMessageResponse"}, "description": "messages value for tenant thread response."}}}, "TenantUpdateHouseholdRequest": {"type": "object", "description": "Request payload for tenant update household.", "required": ["household"], "properties": {"household": {"description": "household value for tenant update household request."}}}, "TenantUpdateMaintenanceTicketRequest": {"type": "object", "description": "Request payload for tenant update maintenance ticket.", "required": ["status"], "properties": {"title": {"type": ["string", "null"], "description": "title value for tenant update maintenance ticket request.", "maxLength": 160, "minLength": 1}, "description": {"type": ["string", "null"], "description": "Human-readable description for the resource or line item.", "maxLength": 2000, "minLength": 1}, "status": {"type": "string", "description": "Current lifecycle or operational status.", "maxLength": 9, "minLength": 4, "pattern": "^(OPEN|CANCELLED)$"}}}, "TenantUpdateMeRequest": {"type": "object", "description": "Request payload for tenant update me.", "properties": {"display_name": {"type": ["string", "null"], "description": "Human-readable display name.", "maxLength": 160, "minLength": 1}, "phone": {"type": ["string", "null"], "description": "Phone number associated with the renter or user.", "maxLength": 40}, "locale": {"type": ["string", "null"], "description": "locale value for tenant update me request.", "maxLength": 16, "minLength": 2}, "timezone": {"type": ["string", "null"], "description": "timezone value for tenant update me request.", "maxLength": 64, "minLength": 1}}}, "TenantUpdateNotificationPreferencesRequest": {"type": "object", "description": "Request payload for tenant update notification preferences.", "properties": {"email_enabled": {"type": ["boolean", "null"], "description": "email enabled value for tenant update notification preferences request."}, "push_enabled": {"type": ["boolean", "null"], "description": "push enabled value for tenant update notification preferences request."}, "invoice_updates": {"type": ["boolean", "null"], "description": "invoice updates value for tenant update notification preferences request."}, "maintenance_updates": {"type": ["boolean", "null"], "description": "maintenance updates value for tenant update notification preferences request."}, "message_updates": {"type": ["boolean", "null"], "description": "message updates value for tenant update notification preferences request."}}}, "TenantUpdateProfileRequest": {"type": "object", "description": "Request payload for tenant update profile.", "required": ["profile"], "properties": {"profile": {"description": "profile value for tenant update profile request."}}}, "UnregisterPushDeviceRequest": {"type": "object", "description": "Request payload for unregister push device.", "required": ["device_token"], "properties": {"device_token": {"type": "string", "description": "device token value for unregister push device request.", "maxLength": 4096, "minLength": 1}}}, "UpdateFeeTemplateRequest": {"type": "object", "description": "Request payload for update fee template.", "required": ["amount"], "properties": {"name": {"type": ["string", "null"], "description": "Human-readable name for the resource.", "maxLength": 120, "minLength": 1}, "fee_type": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/FeeType"}], "description": "Classification of the recurring fee."}, "amount": {"type": "string", "description": "Money amount represented in the API currency unit.", "example": "150000"}, "is_default": {"type": ["boolean", "null"], "description": "Whether this account or setting is the default choice."}}}, "UpdateInvoiceLineRequest": {"type": "object", "description": "Request payload for update invoice line.", "required": ["quantity", "unit_price"], "properties": {"quantity": {"type": "string", "description": "2-dp decimal string; validated >= 0 in the service.", "example": "1"}, "unit_price": {"type": "string", "description": "Unit price used for invoice line calculations.", "example": "1500000"}}}, "UpdateInvoiceRequest": {"type": "object", "description": "Request payload for update invoice.", "properties": {"due_date": {"type": ["string", "null"], "format": "date", "description": "Payment deadline for a draft invoice. It may be earlier than the lease start date for advance-payment workflows."}, "payment_reference": {"type": ["string", "null"], "description": "External or manual reference for payment reconciliation.", "maxLength": 120, "minLength": 1}}}, "UpdateLeaseRequest": {"type": "object", "description": "Request payload for update lease.", "required": ["monthly_rent", "deposit_amount"], "properties": {"end_date": {"type": ["string", "null"], "format": "date", "description": "Lease or report end date."}, "monthly_rent": {"type": "string", "description": "Monthly rent amount for the lease.", "example": "3000000"}, "deposit_amount": {"type": "string", "description": "Deposit amount recorded for the lease.", "example": "3000000"}, "number_of_occupants": {"type": ["integer", "null"], "format": "int32", "description": "Number of occupants assigned to the room or lease.", "minimum": 1}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "UpdateMaintenanceTicketRequest": {"type": "object", "description": "Request payload for update maintenance ticket.", "properties": {"title": {"type": ["string", "null"], "description": "title value for update maintenance ticket request.", "maxLength": 160, "minLength": 1}, "description": {"type": ["string", "null"], "description": "Human-readable description for the resource or line item.", "maxLength": 2000, "minLength": 1}, "priority": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/MaintenanceTicketPriority"}], "description": "priority value for update maintenance ticket request."}, "status": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/MaintenanceTicketStatus"}], "description": "Current lifecycle or operational status."}, "reported_by_name": {"type": ["string", "null"], "description": "reported by name value for update maintenance ticket request.", "maxLength": 160}, "reported_by_contact": {"type": ["string", "null"], "description": "reported by contact value for update maintenance ticket request.", "maxLength": 160}}}, "UpdateMeRequest": {"type": "object", "description": "Request payload for update me.", "properties": {"display_name": {"type": ["string", "null"], "description": "Human-readable display name.", "maxLength": 100}, "email": {"type": ["string", "null"], "format": "email", "description": "Email address associated with the user or renter."}}}, "UpdateMemberRequest": {"type": "object", "description": "Request payload for update member.", "properties": {"role": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/OrganizationRole"}], "description": "Role granted to the user in the relevant scope."}, "status": {"type": ["string", "null"], "description": "Current lifecycle or operational status."}}}, "UpdateMembershipRequest": {"type": "object", "description": "Request payload for update membership.", "required": ["reason", "action_token"], "properties": {"role": {"type": ["string", "null"], "description": "Role granted to the user in the relevant scope."}, "status": {"type": ["string", "null"], "description": "Current lifecycle or operational status."}, "reason": {"type": "string", "description": "Operator-provided reason for a lifecycle action."}, "action_token": {"type": "string", "description": "action token value for update membership request."}}}, "UpdateMeterReadingRequest": {"type": "object", "description": "Request payload for update meter reading.", "properties": {"period": {"type": ["string", "null"], "description": "Billing period in YYYY-MM format.", "maxLength": 7, "minLength": 7, "pattern": "^\\d{4}-\\d{2}$"}, "electricity_previous": {"type": ["number", "null"], "format": "double", "description": "Previous electricity meter reading for the billing period.", "minimum": 0}, "electricity_current": {"type": ["number", "null"], "format": "double", "description": "Current electricity meter reading for the billing period.", "minimum": 0}, "water_previous": {"type": ["number", "null"], "format": "double", "description": "Previous water meter reading for the billing period.", "minimum": 0}, "water_current": {"type": ["number", "null"], "format": "double", "description": "Current water meter reading for the billing period.", "minimum": 0}}}, "UpdateOrganizationRequest": {"type": "object", "description": "Request payload for update organization.", "properties": {"name": {"type": ["string", "null"], "description": "Human-readable name for the resource.", "maxLength": 100, "minLength": 2}, "slug": {"type": ["string", "null"], "description": "URL-safe slug for the resource.", "maxLength": 80}, "status": {"type": ["string", "null"], "description": "Current lifecycle or operational status."}}}, "UpdatePaymentAccountRequest": {"type": "object", "description": "Request payload for update payment account.", "properties": {"property_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for property."}, "clear_property_id": {"type": "boolean", "description": "UUID identifier for clear property."}, "bank_name": {"type": ["string", "null"], "description": "Bank name for the payment account.", "maxLength": 120}, "sepay_bank_code": {"type": ["string", "null"], "description": "sepay bank code value for update payment account request.", "maxLength": 32}, "bank_code": {"type": ["string", "null"], "description": "bank code value for update payment account request."}, "bank_account_number": {"type": ["string", "null"], "description": "Bank account number used for tenant transfers.", "maxLength": 80}, "bank_account_holder": {"type": ["string", "null"], "description": "Name of the bank account holder for transfers.", "maxLength": 120}, "is_default": {"type": ["boolean", "null"], "description": "Whether this account or setting is the default choice."}}}, "UpdatePaymentRequest": {"type": "object", "description": "A recorded payment is an accounting voucher: `amount` and `payment_date` are\n**immutable** after creation (ADR 0019) and are intentionally absent here, so\nthe API has no way to restate or back-date a posted payment. Correct a wrong\namount/date by reversing the payment and recording a new one. Only the\nannotative `method` and `note` are editable.", "properties": {"method": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/PaymentMethod"}], "description": "Payment method used for the payment."}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "UpdatePlanRequest": {"type": "object", "description": "Request payload for update plan.", "required": ["plan_code", "reason", "action_token"], "properties": {"plan_code": {"type": "string", "description": "Commercial plan code assigned to an organization."}, "reason": {"type": "string", "description": "Operator-provided reason for a lifecycle action."}, "action_token": {"type": "string", "description": "action token value for update plan request."}}}, "UpdatePlatformUserRequest": {"type": "object", "description": "Request payload for update platform user.", "required": ["reason", "action_token"], "properties": {"role": {"type": ["string", "null"], "description": "Role granted to the user in the relevant scope."}, "status": {"type": ["string", "null"], "description": "Current lifecycle or operational status."}, "reason": {"type": "string", "description": "Operator-provided reason for a lifecycle action."}, "action_token": {"type": "string", "description": "action token value for update platform user request."}}}, "UpdatePropertyRequest": {"type": "object", "description": "Request payload for update property.", "properties": {"name": {"type": ["string", "null"], "description": "Human-readable name for the resource.", "maxLength": 120, "minLength": 1}, "address": {"type": ["string", "null"], "description": "Street address or address detail for the resource.", "maxLength": 255}, "city": {"type": ["string", "null"], "description": "City portion of the address.", "maxLength": 80}, "district": {"type": ["string", "null"], "description": "District portion of the address.", "maxLength": 80}, "ward": {"type": ["string", "null"], "description": "Ward portion of the address.", "maxLength": 80}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "UpdateRenterRequest": {"type": "object", "description": "Request payload for update renter.", "properties": {"full_name": {"type": ["string", "null"], "description": "Full legal or display name for the person.", "maxLength": 160, "minLength": 1}, "phone": {"type": "string", "description": "Optional renter phone update. When supplied, it must be a Vietnam mobile number such as 0912345678 or +84912345678.", "maxLength": 40, "pattern": "^(0[35789][0-9]{8}|\\+84[35789][0-9]{8})$"}, "email": {"type": ["string", "null"], "format": "email", "description": "Email address associated with the user or renter."}, "identity_number": {"type": ["string", "null"], "description": "Government or landlord-recorded identity number for the renter.", "maxLength": 80}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "UpdateRoomRequest": {"type": "object", "description": "Request payload for update room.", "required": ["base_rent", "default_deposit"], "properties": {"name": {"type": ["string", "null"], "description": "Human-readable name for the resource.", "maxLength": 120, "minLength": 1}, "floor": {"type": ["string", "null"], "description": "Floor label or number where the room is located.", "maxLength": 80}, "status": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/RoomStatus", "description": "Operational intent. `VACANT` clears the operational override; `HIDDEN`\nand `MAINTENANCE` set it; `OCCUPIED` is rejected (occupancy is derived\nfrom the lease, not settable here)."}], "description": "Current lifecycle or operational status."}, "base_rent": {"type": "string", "description": "Default monthly rent amount for the room.", "example": "3000000"}, "default_deposit": {"type": "string", "description": "Default deposit amount used when creating leases.", "example": "3000000"}, "area_m2": {"type": ["number", "null"], "format": "double", "description": "Room area in square meters.", "minimum": 0}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "UpdateRoomStatusRequest": {"type": "object", "description": "Request payload for update room status.", "required": ["status"], "properties": {"status": {"$ref": "#/components/schemas/RoomStatus", "description": "Operational intent (see `UpdateRoomRequest.status`). `OCCUPIED` is\nrejected with `room_occupancy_not_settable`."}, "reason": {"type": ["string", "null"], "description": "Operator-provided reason for a lifecycle action.", "maxLength": 500}}}, "UpdateStatusRequest": {"type": "object", "description": "Request payload for update status.", "required": ["status", "reason", "action_token"], "properties": {"status": {"type": "string", "description": "Current lifecycle or operational status."}, "reason": {"type": "string", "description": "Operator-provided reason for a lifecycle action."}, "action_token": {"type": "string", "description": "action token value for update status request."}}}, "UpsertBillingSettingsRequest": {"type": "object", "description": "Request payload for upsert billing settings.", "required": ["electricity_unit_price", "electricity_fixed_amount", "water_unit_price", "water_fixed_amount"], "properties": {"billing_day": {"type": ["integer", "null"], "format": "int32", "description": "Day of month used as the default billing day.", "maximum": 31, "minimum": 1}, "due_day": {"type": ["integer", "null"], "format": "int32", "description": "Day of month used to calculate invoice due dates.", "maximum": 31, "minimum": 1}, "electricity_pricing_type": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/PricingType"}], "description": "Pricing mode used for electricity charges."}, "electricity_unit_price": {"type": "string", "description": "Unit price applied to electricity usage.", "example": "3500"}, "electricity_fixed_amount": {"type": "string", "description": "Fixed electricity charge applied during invoice generation.", "example": "0"}, "water_pricing_type": {"oneOf": [{"type": "null"}, {"$ref": "#/components/schemas/PricingType"}], "description": "Pricing mode used for water charges."}, "water_unit_price": {"type": "string", "description": "Unit price applied to water usage.", "example": "15000"}, "water_fixed_amount": {"type": "string", "description": "Fixed water charge applied during invoice generation.", "example": "0"}}}, "UpsertListingImage": {"type": "object", "description": "Schema for upsert listing image.", "properties": {"image_url": {"type": ["string", "null"], "description": "image url value for upsert listing image.", "maxLength": 1000}, "media_asset_id": {"type": ["string", "null"], "format": "uuid", "description": "UUID identifier for media asset."}, "alt_text": {"type": ["string", "null"], "description": "alt text value for upsert listing image.", "maxLength": 200}, "sort_order": {"type": ["integer", "null"], "format": "int32", "description": "sort order value for upsert listing image."}}}, "UpsertListingRequest": {"type": "object", "description": "Landlord admin: create or replace the listing overlay for one room.", "required": ["headline"], "properties": {"headline": {"type": "string", "description": "headline value for upsert listing request.", "maxLength": 200, "minLength": 1}, "description": {"type": ["string", "null"], "description": "Human-readable description for the resource or line item.", "maxLength": 4000}, "amenities": {"type": ["array", "null"], "items": {"type": "string"}, "description": "amenities value for upsert listing request."}, "contact_phone": {"type": ["string", "null"], "description": "contact phone value for upsert listing request.", "maxLength": 40}, "zalo_url": {"type": ["string", "null"], "description": "zalo url value for upsert listing request.", "maxLength": 500}, "available_date": {"type": ["string", "null"], "format": "date", "description": "available date value for upsert listing request."}, "min_lease_months": {"type": ["integer", "null"], "format": "int32", "description": "min lease months value for upsert listing request.", "maximum": 60, "minimum": 0}, "images": {"type": ["array", "null"], "items": {"$ref": "#/components/schemas/UpsertListingImage"}, "description": "images value for upsert listing request."}}}, "UpsertPaymentReconciliationSettingsRequest": {"type": "object", "description": "Request payload for upsert payment reconciliation settings.", "required": ["enabled", "risk_acknowledged"], "properties": {"enabled": {"type": "boolean", "description": "enabled value for upsert payment reconciliation settings request."}, "bank_provider": {"type": ["string", "null"], "description": "bank provider value for upsert payment reconciliation settings request.", "maxLength": 80}, "webhook_mode": {"type": ["string", "null"], "description": "webhook mode value for upsert payment reconciliation settings request.", "maxLength": 40}, "sepay_payment_code_prefix": {"type": ["string", "null"], "description": "sepay payment code prefix value for upsert payment reconciliation settings request.", "maxLength": 5, "minLength": 2}, "sepay_webhook_secret": {"type": ["string", "null"], "description": "sepay webhook secret value for upsert payment reconciliation settings request.", "maxLength": 255, "minLength": 16}, "risk_acknowledged": {"type": "boolean", "description": "risk acknowledged value for upsert payment reconciliation settings request."}, "note": {"type": ["string", "null"], "description": "Optional note captured by the operator.", "maxLength": 1000}}}, "UserInfo": {"type": "object", "description": "Schema for user info.", "required": ["id", "username"], "properties": {"id": {"type": "string", "format": "uuid", "description": "Stable UUID identifier for this resource."}, "username": {"type": "string", "description": "Unique username used for login and display."}, "email": {"type": ["string", "null"], "description": "Email address associated with the user or renter."}, "display_name": {"type": ["string", "null"], "description": "Human-readable display name."}}}, "UsernameAvailabilityQuery": {"type": "object", "description": "Schema for username availability query.", "required": ["username"], "properties": {"username": {"type": "string", "description": "Unique username used for login and display.", "maxLength": 50, "minLength": 3}}}, "UsernameAvailabilityResponse": {"type": "object", "description": "Response payload for username availability.", "required": ["username", "available"], "properties": {"username": {"type": "string", "description": "Unique username used for login and display."}, "available": {"type": "boolean", "description": "available value for username availability response."}}}}, "securitySchemes": {"bearerAuth": {"type": "http", "scheme": "bearer", "bearerFormat": "JWT"}, "sepayBankHubApiKey": {"type": "apiKey", "in": "header", "name": "Authorization"}}}, "security": [{"bearerAuth": []}], "tags": [{"name": "Health", "description": "Service health and readiness checks"}, {"name": "Authentication", "description": "Authentication and session lifecycle"}, {"name": "Organizations", "description": "Organization workspace and member management"}, {"name": "Properties", "description": "Property, room, renter, and lease operations"}, {"name": "Billing", "description": "Billing settings, meter readings, invoices, and payments"}, {"name": "Reports", "description": "Dashboard, reports, and CSV exports"}, {"name": "Imports", "description": "CSV import flows for landlord onboarding"}, {"name": "Tenant Portal", "description": "Public tenant invoice and maintenance request flows"}, {"name": "Tenant", "description": "Authenticated tenant and renter self-service APIs"}, {"name": "Tenant Access", "description": "Landlord tenant access, invitation, and audit controls"}, {"name": "Maintenance", "description": "Maintenance ticket workflows"}, {"name": "Operations", "description": "Internal support and audit APIs"}]}