{
 "components": {
  "schemas": {
   "AIDetectionResultCreate": {
    "properties": {
     "annotated_image_uri": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Annotated Image Uri"
     },
     "bbox_height": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Bbox Height"
     },
     "bbox_width": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Bbox Width"
     },
     "bbox_x": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Bbox X"
     },
     "bbox_y": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Bbox Y"
     },
     "camera_id": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Camera Id"
     },
     "caption": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Caption"
     },
     "confidence": {
      "anyOf": [
       {
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "title": "Confidence"
     },
     "count": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Count"
     },
     "executed_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Executed At"
     },
     "label": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Label"
     },
     "latency_ms": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Latency Ms"
     },
     "model_id": {
      "title": "Model Id",
      "type": "integer"
     },
     "task": {
      "title": "Task",
      "type": "string"
     }
    },
    "required": [
     "model_id",
     "task"
    ],
    "title": "AIDetectionResultCreate",
    "type": "object"
   },
   "AIDetectionResultResponse": {
    "properties": {
     "annotated_image_uri": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Annotated Image Uri"
     },
     "bbox_height": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Bbox Height"
     },
     "bbox_width": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Bbox Width"
     },
     "bbox_x": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Bbox X"
     },
     "bbox_y": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Bbox Y"
     },
     "camera_id": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Camera Id"
     },
     "caption": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Caption"
     },
     "confidence": {
      "anyOf": [
       {
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "title": "Confidence"
     },
     "count": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Count"
     },
     "created_at": {
      "format": "date-time",
      "title": "Created At",
      "type": "string"
     },
     "executed_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Executed At"
     },
     "id": {
      "title": "Id",
      "type": "integer"
     },
     "label": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Label"
     },
     "latency_ms": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Latency Ms"
     },
     "model_id": {
      "title": "Model Id",
      "type": "integer"
     },
     "model_name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Model Name"
     },
     "task": {
      "title": "Task",
      "type": "string"
     }
    },
    "required": [
     "id",
     "model_id",
     "task",
     "created_at"
    ],
    "title": "AIDetectionResultResponse",
    "type": "object"
   },
   "AIInferenceJobCreate": {
    "description": "Schema for creating async inference job.",
    "properties": {
     "inputs": {
      "additionalProperties": true,
      "description": "Inference inputs",
      "title": "Inputs",
      "type": "object"
     },
     "model_id": {
      "description": "CloudProviderModel ID to use",
      "title": "Model Id",
      "type": "integer"
     },
     "parameters": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Inference parameters",
      "title": "Parameters"
     }
    },
    "required": [
     "model_id",
     "inputs"
    ],
    "title": "AIInferenceJobCreate",
    "type": "object"
   },
   "AIInferenceJobResponse": {
    "description": "Schema for async inference job response.",
    "properties": {
     "completed_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Completed At"
     },
     "created_at": {
      "format": "date-time",
      "title": "Created At",
      "type": "string"
     },
     "error_message": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Error Message"
     },
     "id": {
      "title": "Id",
      "type": "string"
     },
     "model_id": {
      "title": "Model Id",
      "type": "string"
     },
     "provider": {
      "title": "Provider",
      "type": "string"
     },
     "result_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Result Id"
     },
     "started_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Started At"
     },
     "status": {
      "title": "Status",
      "type": "string"
     },
     "task": {
      "title": "Task",
      "type": "string"
     },
     "user_id": {
      "title": "User Id",
      "type": "integer"
     }
    },
    "required": [
     "id",
     "user_id",
     "model_id",
     "provider",
     "task",
     "status",
     "result_id",
     "error_message",
     "created_at",
     "started_at",
     "completed_at"
    ],
    "title": "AIInferenceJobResponse",
    "type": "object"
   },
   "AIModelCreate": {
    "properties": {
     "assigned_camera_id": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Assigned Camera Id"
     },
     "config": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Config"
     },
     "enabled": {
      "default": true,
      "title": "Enabled",
      "type": "boolean"
     },
     "inference_interval": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "default": 2,
      "title": "Inference Interval"
     },
     "model_name": {
      "title": "Model Name",
      "type": "string"
     },
     "name": {
      "title": "Name",
      "type": "string"
     },
     "recording_path": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Recording Path"
     },
     "source_type": {
      "default": "live",
      "title": "Source Type",
      "type": "string"
     },
     "task": {
      "title": "Task",
      "type": "string"
     }
    },
    "required": [
     "name",
     "model_name",
     "task"
    ],
    "title": "AIModelCreate",
    "type": "object"
   },
   "AIModelResponse": {
    "properties": {
     "assigned_camera_id": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Assigned Camera Id"
     },
     "config": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Config"
     },
     "created_at": {
      "format": "date-time",
      "title": "Created At",
      "type": "string"
     },
     "enabled": {
      "title": "Enabled",
      "type": "boolean"
     },
     "id": {
      "title": "Id",
      "type": "integer"
     },
     "inference_interval": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Inference Interval"
     },
     "model_name": {
      "title": "Model Name",
      "type": "string"
     },
     "name": {
      "title": "Name",
      "type": "string"
     },
     "recording_path": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Recording Path"
     },
     "source_type": {
      "title": "Source Type",
      "type": "string"
     },
     "task": {
      "title": "Task",
      "type": "string"
     },
     "updated_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Updated At"
     }
    },
    "required": [
     "id",
     "name",
     "model_name",
     "task",
     "enabled",
     "source_type",
     "created_at"
    ],
    "title": "AIModelResponse",
    "type": "object"
   },
   "AIModelUpdate": {
    "properties": {
     "assigned_camera_id": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Assigned Camera Id"
     },
     "config": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Config"
     },
     "enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Enabled"
     },
     "inference_interval": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Inference Interval"
     },
     "model_name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Model Name"
     },
     "name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Name"
     },
     "recording_path": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Recording Path"
     },
     "source_type": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Source Type"
     },
     "task": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Task"
     }
    },
    "title": "AIModelUpdate",
    "type": "object"
   },
   "AckIn": {
    "description": "What to silence. Three shapes, and the caller must pick one:\n\n* ``ids`` \u2014 exactly these alerts (\"acknowledge these 25\").\n* ``source_name`` and/or ``severity`` \u2014 every unacknowledged alert in\n  the caller's scope matching them (\"acknowledge all 39 vehicle\n  alarms\"). Added so a paged table's \"all\" button can mean the whole\n  filtered set rather than whichever page happens to be loaded.\n* empty \u2014 every unacknowledged alert in scope. Unchanged.\n\n``ids`` and the filters are mutually exclusive: a body carrying both\nreads as two different intentions, and guessing which one an operator\nmeant is not a thing to do with a control that silences alarms.",
    "properties": {
     "ids": {
      "anyOf": [
       {
        "items": {
         "type": "integer"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "title": "Ids"
     },
     "severity": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Severity"
     },
     "source_name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Source Name"
     }
    },
    "title": "AckIn",
    "type": "object"
   },
   "ActionConfigIn": {
    "description": "Partial update; twilio.auth_token (plaintext) is encrypted at\nrest and NEVER returned \u2014 omit/blank keeps the stored one.",
    "properties": {
     "min_severity": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Min Severity"
     },
     "twilio": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "title": "Twilio"
     },
     "webhook": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "title": "Webhook"
     }
    },
    "title": "ActionConfigIn",
    "type": "object"
   },
   "AppRegisterRequest": {
    "description": "What the SDK POSTs on boot: where the app lives + its manifest.",
    "properties": {
     "manifest": {
      "additionalProperties": true,
      "title": "Manifest",
      "type": "object"
     },
     "sdk_version": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Sdk Version"
     },
     "url": {
      "title": "Url",
      "type": "string"
     },
     "wants_key": {
      "default": false,
      "title": "Wants Key",
      "type": "boolean"
     }
    },
    "required": [
     "url",
     "manifest"
    ],
    "title": "AppRegisterRequest",
    "type": "object"
   },
   "AuditLogList": {
    "properties": {
     "logs": {
      "items": {
       "$ref": "#/components/schemas/AuditLogResponse"
      },
      "title": "Logs",
      "type": "array"
     },
     "total": {
      "title": "Total",
      "type": "integer"
     }
    },
    "required": [
     "logs",
     "total"
    ],
    "title": "AuditLogList",
    "type": "object"
   },
   "AuditLogResponse": {
    "properties": {
     "action": {
      "title": "Action",
      "type": "string"
     },
     "details": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Details"
     },
     "entity_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Entity Id"
     },
     "entity_type": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Entity Type"
     },
     "id": {
      "title": "Id",
      "type": "integer"
     },
     "ip": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Ip"
     },
     "timestamp": {
      "format": "date-time",
      "title": "Timestamp",
      "type": "string"
     },
     "user_agent": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "User Agent"
     },
     "user_id": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "User Id"
     },
     "username": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Username"
     }
    },
    "required": [
     "id",
     "timestamp",
     "action"
    ],
    "title": "AuditLogResponse",
    "type": "object"
   },
   "Body_declare_skill_camera_api_v1_skills__skill_id__cameras__camera_id__put": {
    "properties": {
     "consumer": {
      "title": "Consumer",
      "type": "string"
     },
     "params": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "title": "Params"
     }
    },
    "required": [
     "consumer"
    ],
    "title": "Body_declare_skill_camera_api_v1_skills__skill_id__cameras__camera_id__put",
    "type": "object"
   },
   "Body_login_for_access_token_api_v1_auth_login_post": {
    "properties": {
     "client_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Client Id"
     },
     "client_secret": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "format": "password",
      "title": "Client Secret"
     },
     "grant_type": {
      "anyOf": [
       {
        "pattern": "^password$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Grant Type"
     },
     "password": {
      "format": "password",
      "title": "Password",
      "type": "string"
     },
     "scope": {
      "default": "",
      "title": "Scope",
      "type": "string"
     },
     "username": {
      "title": "Username",
      "type": "string"
     }
    },
    "required": [
     "username",
     "password"
    ],
    "title": "Body_login_for_access_token_api_v1_auth_login_post",
    "type": "object"
   },
   "Body_refresh_access_token_api_v1_auth_refresh_post": {
    "properties": {
     "refresh_token": {
      "title": "Refresh Token",
      "type": "string"
     }
    },
    "required": [
     "refresh_token"
    ],
    "title": "Body_refresh_access_token_api_v1_auth_refresh_post",
    "type": "object"
   },
   "Body_upload_media_source_settings_api_v1_media_source_settings_upload_post": {
    "properties": {
     "ca_bundle_file": {
      "anyOf": [
       {
        "contentMediaType": "application/octet-stream",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "CA bundle PEM file (optional)",
      "title": "Ca Bundle File"
     },
     "cert_file": {
      "anyOf": [
       {
        "contentMediaType": "application/octet-stream",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "TLS certificate PEM file",
      "title": "Cert File"
     },
     "key_file": {
      "anyOf": [
       {
        "contentMediaType": "application/octet-stream",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "TLS private key PEM file",
      "title": "Key File"
     }
    },
    "title": "Body_upload_media_source_settings_api_v1_media_source_settings_upload_post",
    "type": "object"
   },
   "CameraAssignment": {
    "description": "One per-camera capability assignment \u2014 \"this camera does <skill>\".\n\n``skill`` names a capability (``license_plate_recognition``,\n``object_detection``, ``occupancy_counting``, \u2026). Deliberately an open\nvocabulary in slice 1: the catalog UI's requires_tasks validation\n(consumer 3 in docs/design/per-camera-assignment.md) is where \"is this\ncapability actually installed?\" gets enforced, so an assignment can be\ndeclared before its adapter/app exists. ``labels`` optionally NARROWS\na detection-shaped skill to specific classes (\"camera 4 also wants\ntrucks\") \u2014 it may narrow configuration, never replace it.",
    "properties": {
     "labels": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "title": "Labels"
     },
     "skill": {
      "maxLength": 64,
      "minLength": 2,
      "pattern": "^[a-z][a-z0-9_]*$",
      "title": "Skill",
      "type": "string"
     }
    },
    "required": [
     "skill"
    ],
    "title": "CameraAssignment",
    "type": "object"
   },
   "CameraConfigCreate": {
    "properties": {
     "auto_restart": {
      "default": true,
      "title": "Auto Restart",
      "type": "boolean"
     },
     "camera_id": {
      "title": "Camera Id",
      "type": "integer"
     },
     "extra_options": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Extra Options"
     },
     "max_restart_attempts": {
      "default": 3,
      "title": "Max Restart Attempts",
      "type": "integer"
     },
     "proxy_enabled": {
      "default": false,
      "title": "Proxy Enabled",
      "type": "boolean"
     },
     "recording_enabled": {
      "default": false,
      "title": "Recording Enabled",
      "type": "boolean"
     },
     "recording_path": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Recording Path"
     },
     "recording_segment_seconds": {
      "title": "Recording Segment Seconds",
      "type": "integer"
     },
     "rtmp_publisher": {
      "default": false,
      "title": "Rtmp Publisher",
      "type": "boolean"
     },
     "rtsp_transport": {
      "anyOf": [
       {
        "pattern": "^(udp|tcp|auto)?$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Rtsp Transport"
     },
     "source_url": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Source Url"
     },
     "stream_protocol": {
      "default": "rtsp",
      "pattern": "^(rtsp|rtmp|webrtc)$",
      "title": "Stream Protocol",
      "type": "string"
     },
     "transport_security": {
      "default": "rtsps_preferred",
      "pattern": "^(rtsps_required|rtsps_preferred|plaintext_allowed)$",
      "title": "Transport Security",
      "type": "string"
     },
     "webrtc_publisher": {
      "default": false,
      "title": "Webrtc Publisher",
      "type": "boolean"
     }
    },
    "required": [
     "camera_id"
    ],
    "title": "CameraConfigCreate",
    "type": "object"
   },
   "CameraConfigResponse": {
    "properties": {
     "auto_restart": {
      "default": true,
      "title": "Auto Restart",
      "type": "boolean"
     },
     "camera_id": {
      "title": "Camera Id",
      "type": "integer"
     },
     "extra_options": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Extra Options"
     },
     "id": {
      "title": "Id",
      "type": "integer"
     },
     "last_provisioned_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Last Provisioned At"
     },
     "last_stream_start": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Last Stream Start"
     },
     "max_restart_attempts": {
      "default": 3,
      "title": "Max Restart Attempts",
      "type": "integer"
     },
     "proxy_enabled": {
      "default": false,
      "title": "Proxy Enabled",
      "type": "boolean"
     },
     "recording_enabled": {
      "default": false,
      "title": "Recording Enabled",
      "type": "boolean"
     },
     "recording_path": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Recording Path"
     },
     "recording_segment_seconds": {
      "title": "Recording Segment Seconds",
      "type": "integer"
     },
     "rtmp_publisher": {
      "default": false,
      "title": "Rtmp Publisher",
      "type": "boolean"
     },
     "rtsp_transport": {
      "anyOf": [
       {
        "pattern": "^(udp|tcp|auto)?$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Rtsp Transport"
     },
     "source_url": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Source Url"
     },
     "stream_active": {
      "default": false,
      "title": "Stream Active",
      "type": "boolean"
     },
     "stream_failures": {
      "default": 0,
      "title": "Stream Failures",
      "type": "integer"
     },
     "stream_protocol": {
      "default": "rtsp",
      "pattern": "^(rtsp|rtmp|webrtc)$",
      "title": "Stream Protocol",
      "type": "string"
     },
     "transport_security": {
      "default": "rtsps_preferred",
      "pattern": "^(rtsps_required|rtsps_preferred|plaintext_allowed)$",
      "title": "Transport Security",
      "type": "string"
     },
     "transport_security_operator_set": {
      "default": false,
      "title": "Transport Security Operator Set",
      "type": "boolean"
     },
     "transport_security_probe_result": {
      "default": "not_probed",
      "pattern": "^(supported|not_supported|inconclusive|not_probed)$",
      "title": "Transport Security Probe Result",
      "type": "string"
     },
     "transport_security_probed_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Transport Security Probed At"
     },
     "webrtc_publisher": {
      "default": false,
      "title": "Webrtc Publisher",
      "type": "boolean"
     }
    },
    "required": [
     "id",
     "camera_id"
    ],
    "title": "CameraConfigResponse",
    "type": "object"
   },
   "CameraConfigUpdate": {
    "properties": {
     "auto_restart": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Auto Restart"
     },
     "extra_options": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Extra Options"
     },
     "max_restart_attempts": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Max Restart Attempts"
     },
     "proxy_enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Proxy Enabled"
     },
     "recording_enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Recording Enabled"
     },
     "recording_path": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Recording Path"
     },
     "recording_segment_seconds": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Recording Segment Seconds"
     },
     "rtmp_publisher": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Rtmp Publisher"
     },
     "rtsp_transport": {
      "anyOf": [
       {
        "pattern": "^(udp|tcp|auto)?$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Rtsp Transport"
     },
     "source_url": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Source Url"
     },
     "stream_protocol": {
      "anyOf": [
       {
        "pattern": "^(rtsp|rtmp|webrtc)$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Stream Protocol"
     },
     "transport_security": {
      "anyOf": [
       {
        "pattern": "^(rtsps_required|rtsps_preferred|plaintext_allowed)$",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Transport Security"
     },
     "webrtc_publisher": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Webrtc Publisher"
     }
    },
    "title": "CameraConfigUpdate",
    "type": "object"
   },
   "CameraCreate": {
    "description": "Schema for creating a new camera.",
    "properties": {
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Description"
     },
     "display_aspect_ratio": {
      "anyOf": [
       {
        "maxLength": 16,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Display Aspect Ratio"
     },
     "firmware_version": {
      "anyOf": [
       {
        "maxLength": 100,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Firmware Version"
     },
     "hardware_id": {
      "anyOf": [
       {
        "maxLength": 100,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Hardware Id"
     },
     "ip_address": {
      "maxLength": 45,
      "title": "Ip Address",
      "type": "string"
     },
     "location": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Location"
     },
     "manufacturer": {
      "anyOf": [
       {
        "maxLength": 100,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Manufacturer"
     },
     "model": {
      "anyOf": [
       {
        "maxLength": 100,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Model"
     },
     "name": {
      "maxLength": 100,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "password": {
      "anyOf": [
       {
        "maxLength": 255,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Password"
     },
     "port": {
      "default": 554,
      "maximum": 65535.0,
      "minimum": 1.0,
      "title": "Port",
      "type": "integer"
     },
     "rtsp_url": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Rtsp Url"
     },
     "serial_number": {
      "anyOf": [
       {
        "maxLength": 100,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Serial Number"
     },
     "status": {
      "anyOf": [
       {
        "maxLength": 20,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "default": "unknown",
      "title": "Status"
     },
     "substream_url": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Substream Url"
     },
     "username": {
      "anyOf": [
       {
        "maxLength": 50,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Username"
     },
     "vlan": {
      "anyOf": [
       {
        "maxLength": 50,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Vlan"
     }
    },
    "required": [
     "name",
     "ip_address"
    ],
    "title": "CameraCreate",
    "type": "object"
   },
   "CameraHardDeleteRequest": {
    "description": "Confirmation payload for permanently deleting a binned camera.\n\nThe phrase must exactly match \"hard delete <camera name> and it's\nrecording\"; the server validates it against the stored camera name.",
    "properties": {
     "confirmation_phrase": {
      "maxLength": 200,
      "minLength": 1,
      "title": "Confirmation Phrase",
      "type": "string"
     }
    },
    "required": [
     "confirmation_phrase"
    ],
    "title": "CameraHardDeleteRequest",
    "type": "object"
   },
   "CameraList": {
    "properties": {
     "cameras": {
      "items": {
       "$ref": "#/components/schemas/CameraResponse"
      },
      "title": "Cameras",
      "type": "array"
     },
     "total": {
      "title": "Total",
      "type": "integer"
     }
    },
    "required": [
     "cameras",
     "total"
    ],
    "title": "CameraList",
    "type": "object"
   },
   "CameraPermissionAssign": {
    "description": "Schema to assign camera permissions to a user.",
    "properties": {
     "can_manage": {
      "default": false,
      "title": "Can Manage",
      "type": "boolean"
     },
     "can_view": {
      "default": true,
      "title": "Can View",
      "type": "boolean"
     },
     "user_id": {
      "title": "User Id",
      "type": "integer"
     }
    },
    "required": [
     "user_id"
    ],
    "title": "CameraPermissionAssign",
    "type": "object"
   },
   "CameraPermissionEntry": {
    "description": "One row of ``GET /cameras/{id}/permissions``: a grant, or the\nowner (who holds every right implicitly).",
    "properties": {
     "can_manage": {
      "title": "Can Manage",
      "type": "boolean"
     },
     "can_view": {
      "title": "Can View",
      "type": "boolean"
     },
     "is_owner": {
      "default": false,
      "title": "Is Owner",
      "type": "boolean"
     },
     "user_id": {
      "title": "User Id",
      "type": "integer"
     },
     "username": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Username"
     }
    },
    "required": [
     "user_id",
     "can_view",
     "can_manage"
    ],
    "title": "CameraPermissionEntry",
    "type": "object"
   },
   "CameraPermissionResponse": {
    "description": "Schema for camera permission response.",
    "properties": {
     "camera_id": {
      "title": "Camera Id",
      "type": "integer"
     },
     "can_manage": {
      "title": "Can Manage",
      "type": "boolean"
     },
     "can_view": {
      "title": "Can View",
      "type": "boolean"
     },
     "user_id": {
      "title": "User Id",
      "type": "integer"
     }
    },
    "required": [
     "user_id",
     "camera_id",
     "can_view",
     "can_manage"
    ],
    "title": "CameraPermissionResponse",
    "type": "object"
   },
   "CameraResponse": {
    "properties": {
     "assignments": {
      "anyOf": [
       {
        "items": {
         "$ref": "#/components/schemas/CameraAssignment"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "title": "Assignments"
     },
     "created_at": {
      "format": "date-time",
      "title": "Created At",
      "type": "string"
     },
     "deleted_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Deleted At"
     },
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Description"
     },
     "display_aspect_ratio": {
      "anyOf": [
       {
        "maxLength": 16,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Display Aspect Ratio"
     },
     "firmware_version": {
      "anyOf": [
       {
        "maxLength": 100,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Firmware Version"
     },
     "hardware_id": {
      "anyOf": [
       {
        "maxLength": 100,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Hardware Id"
     },
     "id": {
      "title": "Id",
      "type": "integer"
     },
     "ip_address": {
      "maxLength": 45,
      "title": "Ip Address",
      "type": "string"
     },
     "is_active": {
      "title": "Is Active",
      "type": "boolean"
     },
     "last_recording_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Last Recording At"
     },
     "live_online": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Live Online"
     },
     "location": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Location"
     },
     "manufacturer": {
      "anyOf": [
       {
        "maxLength": 100,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Manufacturer"
     },
     "mediamtx_provisioned": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Mediamtx Provisioned"
     },
     "model": {
      "anyOf": [
       {
        "maxLength": 100,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Model"
     },
     "name": {
      "maxLength": 100,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "owner_id": {
      "title": "Owner Id",
      "type": "integer"
     },
     "port": {
      "default": 554,
      "maximum": 65535.0,
      "minimum": 1.0,
      "title": "Port",
      "type": "integer"
     },
     "recording_enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Recording Enabled"
     },
     "recording_state": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Recording State"
     },
     "rtsp_url": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Rtsp Url"
     },
     "serial_number": {
      "anyOf": [
       {
        "maxLength": 100,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Serial Number"
     },
     "status": {
      "anyOf": [
       {
        "maxLength": 20,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "default": "unknown",
      "title": "Status"
     },
     "stream_action": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Stream Action"
     },
     "stream_warning": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Stream Warning"
     },
     "substream_url": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Substream Url"
     },
     "updated_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Updated At"
     },
     "username": {
      "anyOf": [
       {
        "maxLength": 50,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Username"
     },
     "vlan": {
      "anyOf": [
       {
        "maxLength": 50,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Vlan"
     }
    },
    "required": [
     "name",
     "ip_address",
     "id",
     "owner_id",
     "is_active",
     "created_at"
    ],
    "title": "CameraResponse",
    "type": "object"
   },
   "CameraUpdate": {
    "description": "Schema for updating a camera.",
    "properties": {
     "assignments": {
      "anyOf": [
       {
        "items": {
         "$ref": "#/components/schemas/CameraAssignment"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "title": "Assignments"
     },
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Description"
     },
     "display_aspect_ratio": {
      "anyOf": [
       {
        "maxLength": 16,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Display Aspect Ratio"
     },
     "ip_address": {
      "anyOf": [
       {
        "maxLength": 45,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Ip Address"
     },
     "is_active": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Is Active"
     },
     "location": {
      "anyOf": [
       {
        "maxLength": 200,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Location"
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 100,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Name"
     },
     "password": {
      "anyOf": [
       {
        "maxLength": 255,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Password"
     },
     "port": {
      "anyOf": [
       {
        "maximum": 65535.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Port"
     },
     "rtsp_url": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Rtsp Url"
     },
     "status": {
      "anyOf": [
       {
        "maxLength": 20,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Status"
     },
     "substream_url": {
      "anyOf": [
       {
        "maxLength": 500,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Substream Url"
     },
     "username": {
      "anyOf": [
       {
        "maxLength": 50,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Username"
     },
     "vlan": {
      "anyOf": [
       {
        "maxLength": 50,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Vlan"
     }
    },
    "title": "CameraUpdate",
    "type": "object"
   },
   "CameraUserCreate": {
    "properties": {
     "level": {
      "default": "Operator",
      "title": "Level",
      "type": "string"
     },
     "password": {
      "title": "Password",
      "type": "string"
     },
     "username": {
      "title": "Username",
      "type": "string"
     }
    },
    "required": [
     "username",
     "password"
    ],
    "title": "CameraUserCreate",
    "type": "object"
   },
   "CapabilitiesResponse": {
    "properties": {
     "adapters": {
      "additionalProperties": true,
      "title": "Adapters",
      "type": "object"
     },
     "kai_c": {
      "additionalProperties": true,
      "title": "Kai C",
      "type": "object"
     }
    },
    "required": [
     "kai_c",
     "adapters"
    ],
    "title": "CapabilitiesResponse",
    "type": "object"
   },
   "CloudInferenceRequest": {
    "description": "Schema for synchronous cloud inference request.",
    "properties": {
     "inputs": {
      "additionalProperties": true,
      "description": "Inference inputs (image URL, text, etc.)",
      "title": "Inputs",
      "type": "object"
     },
     "model_id": {
      "description": "CloudProviderModel ID to use",
      "title": "Model Id",
      "type": "integer"
     },
     "parameters": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Inference parameters",
      "title": "Parameters"
     }
    },
    "required": [
     "model_id",
     "inputs"
    ],
    "title": "CloudInferenceRequest",
    "type": "object"
   },
   "CloudInferenceResponse": {
    "description": "Schema for cloud inference result.",
    "properties": {
     "error_message": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Error Message"
     },
     "executed_at": {
      "format": "date-time",
      "title": "Executed At",
      "type": "string"
     },
     "id": {
      "title": "Id",
      "type": "string"
     },
     "latency_ms": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Latency Ms"
     },
     "model_id": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Model Id"
     },
     "model_identifier": {
      "title": "Model Identifier",
      "type": "string"
     },
     "provider": {
      "title": "Provider",
      "type": "string"
     },
     "result_json": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Result Json"
     },
     "status": {
      "title": "Status",
      "type": "string"
     },
     "task": {
      "title": "Task",
      "type": "string"
     },
     "user_id": {
      "title": "User Id",
      "type": "integer"
     }
    },
    "required": [
     "id",
     "user_id",
     "model_id",
     "provider",
     "model_identifier",
     "task",
     "status",
     "result_json",
     "error_message",
     "latency_ms",
     "executed_at"
    ],
    "title": "CloudInferenceResponse",
    "type": "object"
   },
   "CloudProviderCredentialCreate": {
    "description": "Schema for creating a new cloud provider credential.",
    "properties": {
     "account_info": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "description": "Optional metadata",
      "title": "Account Info"
     },
     "provider": {
      "description": "Provider name (e.g., 'huggingface')",
      "maxLength": 50,
      "minLength": 1,
      "title": "Provider",
      "type": "string"
     },
     "token": {
      "description": "API token (will be encrypted)",
      "minLength": 1,
      "title": "Token",
      "type": "string"
     }
    },
    "required": [
     "provider",
     "token"
    ],
    "title": "CloudProviderCredentialCreate",
    "type": "object"
   },
   "CloudProviderCredentialResponse": {
    "description": "Schema for cloud provider credential response (without token).",
    "properties": {
     "account_info": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Account Info"
     },
     "created_at": {
      "format": "date-time",
      "title": "Created At",
      "type": "string"
     },
     "id": {
      "title": "Id",
      "type": "string"
     },
     "provider": {
      "title": "Provider",
      "type": "string"
     },
     "updated_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Updated At"
     },
     "user_id": {
      "title": "User Id",
      "type": "integer"
     }
    },
    "required": [
     "id",
     "user_id",
     "provider",
     "account_info",
     "created_at",
     "updated_at"
    ],
    "title": "CloudProviderCredentialResponse",
    "type": "object"
   },
   "CloudProviderModelCreate": {
    "description": "Schema for creating a cloud provider model configuration.",
    "properties": {
     "config": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "description": "Model configuration as JSON string",
      "title": "Config"
     },
     "credential_id": {
      "description": "UUID of the credential to use",
      "title": "Credential Id",
      "type": "string"
     },
     "enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "default": true,
      "description": "Whether model is enabled",
      "title": "Enabled"
     },
     "model_id": {
      "description": "Model identifier (e.g., 'Salesforce/blip-image-captioning-base')",
      "title": "Model Id",
      "type": "string"
     },
     "name": {
      "description": "Friendly name",
      "maxLength": 100,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "provider": {
      "description": "Provider name (e.g., 'huggingface')",
      "title": "Provider",
      "type": "string"
     },
     "task": {
      "description": "Task type (e.g., 'image-classification', 'object-detection')",
      "title": "Task",
      "type": "string"
     }
    },
    "required": [
     "name",
     "provider",
     "credential_id",
     "model_id",
     "task"
    ],
    "title": "CloudProviderModelCreate",
    "type": "object"
   },
   "CloudProviderModelResponse": {
    "description": "Schema for cloud provider model response.",
    "properties": {
     "config": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Config"
     },
     "created_at": {
      "format": "date-time",
      "title": "Created At",
      "type": "string"
     },
     "credential_id": {
      "title": "Credential Id",
      "type": "string"
     },
     "enabled": {
      "title": "Enabled",
      "type": "boolean"
     },
     "id": {
      "title": "Id",
      "type": "integer"
     },
     "model_id": {
      "title": "Model Id",
      "type": "string"
     },
     "name": {
      "title": "Name",
      "type": "string"
     },
     "provider": {
      "title": "Provider",
      "type": "string"
     },
     "task": {
      "title": "Task",
      "type": "string"
     },
     "updated_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Updated At"
     },
     "user_id": {
      "title": "User Id",
      "type": "integer"
     }
    },
    "required": [
     "id",
     "user_id",
     "name",
     "provider",
     "credential_id",
     "model_id",
     "task",
     "config",
     "enabled",
     "created_at"
    ],
    "title": "CloudProviderModelResponse",
    "type": "object"
   },
   "CloudRecordingSettings": {
    "properties": {
     "access_key": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Access Key"
     },
     "bucket": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Bucket"
     },
     "enabled": {
      "default": false,
      "title": "Enabled",
      "type": "boolean"
     },
     "region": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Region"
     },
     "secret_key": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Secret Key"
     },
     "server_url": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Server Url"
     },
     "storage_class": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Storage Class"
     },
     "use_byok": {
      "default": true,
      "title": "Use Byok",
      "type": "boolean"
     }
    },
    "title": "CloudRecordingSettings",
    "type": "object"
   },
   "CloudSettings": {
    "properties": {
     "recording": {
      "$ref": "#/components/schemas/CloudRecordingSettings",
      "default": {
       "enabled": false,
       "use_byok": true
      }
     },
     "streaming": {
      "$ref": "#/components/schemas/CloudStreamingSettings",
      "default": {
       "enabled": false,
       "encryption": "dtls-srtp",
       "protocol": "webrtc",
       "video_codec": "h264"
      }
     }
    },
    "title": "CloudSettings",
    "type": "object"
   },
   "CloudStreamTargetCreate": {
    "description": "Schema for creating/updating a cloud stream target.",
    "properties": {
     "audio_bitrate": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "default": "128k",
      "title": "Audio Bitrate"
     },
     "audio_codec": {
      "default": "aac",
      "enum": [
       "copy",
       "aac"
      ],
      "title": "Audio Codec",
      "type": "string"
     },
     "camera_id": {
      "title": "Camera Id",
      "type": "integer"
     },
     "enabled": {
      "default": false,
      "title": "Enabled",
      "type": "boolean"
     },
     "max_reconnect_attempts": {
      "default": 5,
      "maximum": 20.0,
      "minimum": 0.0,
      "title": "Max Reconnect Attempts",
      "type": "integer"
     },
     "protocol": {
      "default": "rtmp",
      "enum": [
       "rtmp",
       "rtmps",
       "srt"
      ],
      "title": "Protocol",
      "type": "string"
     },
     "reconnect_delay_seconds": {
      "default": 5,
      "maximum": 60.0,
      "minimum": 1.0,
      "title": "Reconnect Delay Seconds",
      "type": "integer"
     },
     "server_url": {
      "default": "",
      "title": "Server Url",
      "type": "string"
     },
     "stream_key": {
      "default": "",
      "title": "Stream Key",
      "type": "string"
     },
     "target_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Target Id"
     },
     "use_custom_ca": {
      "default": false,
      "title": "Use Custom Ca",
      "type": "boolean"
     },
     "use_tls": {
      "default": false,
      "title": "Use Tls",
      "type": "boolean"
     },
     "video_bitrate": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Video Bitrate"
     },
     "video_codec": {
      "default": "copy",
      "enum": [
       "copy",
       "libx264",
       "libx265"
      ],
      "title": "Video Codec",
      "type": "string"
     }
    },
    "required": [
     "camera_id"
    ],
    "title": "CloudStreamTargetCreate",
    "type": "object"
   },
   "CloudStreamingSettings": {
    "properties": {
     "auth_token": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Auth Token"
     },
     "enabled": {
      "default": false,
      "title": "Enabled",
      "type": "boolean"
     },
     "encryption": {
      "default": "dtls-srtp",
      "enum": [
       "none",
       "dtls-srtp",
       "aes-128",
       "sample-aes"
      ],
      "title": "Encryption",
      "type": "string"
     },
     "protocol": {
      "default": "webrtc",
      "enum": [
       "webrtc",
       "rtmp",
       "hls"
      ],
      "title": "Protocol",
      "type": "string"
     },
     "server_url": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Server Url"
     },
     "video_codec": {
      "default": "h264",
      "enum": [
       "h264",
       "h265",
       "vp9",
       "av1"
      ],
      "title": "Video Codec",
      "type": "string"
     }
    },
    "title": "CloudStreamingSettings",
    "type": "object"
   },
   "CloudUpdate": {
    "properties": {
     "enabled": {
      "title": "Enabled",
      "type": "boolean"
     }
    },
    "required": [
     "enabled"
    ],
    "title": "CloudUpdate",
    "type": "object"
   },
   "ConfigBackupRequest": {
    "properties": {
     "secret_key": {
      "title": "Secret Key",
      "type": "string"
     }
    },
    "required": [
     "secret_key"
    ],
    "title": "ConfigBackupRequest",
    "type": "object"
   },
   "CustomWindowLayout": {
    "properties": {
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Description"
     },
     "enabled": {
      "default": true,
      "title": "Enabled",
      "type": "boolean"
     },
     "grid_columns": {
      "default": 4,
      "maximum": 8.0,
      "minimum": 1.0,
      "title": "Grid Columns",
      "type": "integer"
     },
     "grid_rows": {
      "default": 4,
      "maximum": 8.0,
      "minimum": 1.0,
      "title": "Grid Rows",
      "type": "integer"
     },
     "id": {
      "maxLength": 50,
      "minLength": 1,
      "title": "Id",
      "type": "string"
     },
     "name": {
      "maxLength": 100,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "tiles": {
      "default": [],
      "items": {
       "additionalProperties": {
        "type": "integer"
       },
       "type": "object"
      },
      "title": "Tiles",
      "type": "array"
     }
    },
    "required": [
     "id",
     "name"
    ],
    "title": "CustomWindowLayout",
    "type": "object"
   },
   "DeletedCameraInfo": {
    "description": "A binned camera as shown on the Deleted Cameras page.",
    "properties": {
     "deleted_at": {
      "format": "date-time",
      "title": "Deleted At",
      "type": "string"
     },
     "id": {
      "title": "Id",
      "type": "integer"
     },
     "ip_address": {
      "title": "Ip Address",
      "type": "string"
     },
     "location": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Location"
     },
     "name": {
      "title": "Name",
      "type": "string"
     },
     "owner_id": {
      "title": "Owner Id",
      "type": "integer"
     },
     "path": {
      "title": "Path",
      "type": "string"
     }
    },
    "required": [
     "id",
     "name",
     "ip_address",
     "owner_id",
     "deleted_at",
     "path"
    ],
    "title": "DeletedCameraInfo",
    "type": "object"
   },
   "DeletedCameraList": {
    "properties": {
     "cameras": {
      "items": {
       "$ref": "#/components/schemas/DeletedCameraInfo"
      },
      "title": "Cameras",
      "type": "array"
     },
     "total": {
      "title": "Total",
      "type": "integer"
     }
    },
    "required": [
     "cameras",
     "total"
    ],
    "title": "DeletedCameraList",
    "type": "object"
   },
   "DeviceLabel": {
    "properties": {
     "label": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Label"
     }
    },
    "title": "DeviceLabel",
    "type": "object"
   },
   "EgressAllowIn": {
    "properties": {
     "allow": {
      "default": [],
      "items": {
       "type": "string"
      },
      "title": "Allow",
      "type": "array"
     }
    },
    "title": "EgressAllowIn",
    "type": "object"
   },
   "EgressCheckIn": {
    "properties": {
     "client_ip": {
      "title": "Client Ip",
      "type": "string"
     },
     "host": {
      "title": "Host",
      "type": "string"
     },
     "port": {
      "default": 443,
      "title": "Port",
      "type": "integer"
     }
    },
    "required": [
     "client_ip",
     "host"
    ],
    "title": "EgressCheckIn",
    "type": "object"
   },
   "EncoderUpdate": {
    "properties": {
     "bitrate": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Bitrate"
     },
     "fps": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Fps"
     },
     "gov_length": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Gov Length"
     },
     "height": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Height"
     },
     "width": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Width"
     }
    },
    "title": "EncoderUpdate",
    "type": "object"
   },
   "EnforcementUpdate": {
    "properties": {
     "active": {
      "title": "Active",
      "type": "boolean"
     }
    },
    "required": [
     "active"
    ],
    "title": "EnforcementUpdate",
    "type": "object"
   },
   "FirewallRuleCreate": {
    "properties": {
     "action": {
      "default": "allow",
      "enum": [
       "allow",
       "deny"
      ],
      "title": "Action",
      "type": "string"
     },
     "direction": {
      "default": "inbound",
      "enum": [
       "inbound",
       "outbound"
      ],
      "title": "Direction",
      "type": "string"
     },
     "enabled": {
      "default": true,
      "title": "Enabled",
      "type": "boolean"
     },
     "name": {
      "maxLength": 100,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "port_from": {
      "anyOf": [
       {
        "maximum": 65535.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Port From"
     },
     "port_to": {
      "anyOf": [
       {
        "maximum": 65535.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Port To"
     },
     "priority": {
      "default": 100,
      "maximum": 100000.0,
      "minimum": 0.0,
      "title": "Priority",
      "type": "integer"
     },
     "protocol": {
      "default": "tcp",
      "enum": [
       "tcp",
       "udp",
       "any"
      ],
      "title": "Protocol",
      "type": "string"
     },
     "sources": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Sources"
     }
    },
    "required": [
     "name"
    ],
    "title": "FirewallRuleCreate",
    "type": "object"
   },
   "FirewallRuleList": {
    "properties": {
     "rules": {
      "items": {
       "$ref": "#/components/schemas/FirewallRuleResponse"
      },
      "title": "Rules",
      "type": "array"
     },
     "total": {
      "title": "Total",
      "type": "integer"
     }
    },
    "required": [
     "rules",
     "total"
    ],
    "title": "FirewallRuleList",
    "type": "object"
   },
   "FirewallRuleResponse": {
    "properties": {
     "action": {
      "default": "allow",
      "enum": [
       "allow",
       "deny"
      ],
      "title": "Action",
      "type": "string"
     },
     "created_at": {
      "format": "date-time",
      "title": "Created At",
      "type": "string"
     },
     "direction": {
      "default": "inbound",
      "enum": [
       "inbound",
       "outbound"
      ],
      "title": "Direction",
      "type": "string"
     },
     "enabled": {
      "default": true,
      "title": "Enabled",
      "type": "boolean"
     },
     "hit_count": {
      "title": "Hit Count",
      "type": "integer"
     },
     "id": {
      "title": "Id",
      "type": "integer"
     },
     "name": {
      "maxLength": 100,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "port_from": {
      "anyOf": [
       {
        "maximum": 65535.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Port From"
     },
     "port_to": {
      "anyOf": [
       {
        "maximum": 65535.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Port To"
     },
     "priority": {
      "default": 100,
      "maximum": 100000.0,
      "minimum": 0.0,
      "title": "Priority",
      "type": "integer"
     },
     "protocol": {
      "default": "tcp",
      "enum": [
       "tcp",
       "udp",
       "any"
      ],
      "title": "Protocol",
      "type": "string"
     },
     "sources": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Sources"
     },
     "updated_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Updated At"
     }
    },
    "required": [
     "name",
     "id",
     "hit_count",
     "created_at",
     "updated_at"
    ],
    "title": "FirewallRuleResponse",
    "type": "object"
   },
   "FirewallRuleUpdate": {
    "properties": {
     "action": {
      "anyOf": [
       {
        "enum": [
         "allow",
         "deny"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Action"
     },
     "direction": {
      "anyOf": [
       {
        "enum": [
         "inbound",
         "outbound"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Direction"
     },
     "enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Enabled"
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 100,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Name"
     },
     "port_from": {
      "anyOf": [
       {
        "maximum": 65535.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Port From"
     },
     "port_to": {
      "anyOf": [
       {
        "maximum": 65535.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Port To"
     },
     "priority": {
      "anyOf": [
       {
        "maximum": 100000.0,
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Priority"
     },
     "protocol": {
      "anyOf": [
       {
        "enum": [
         "tcp",
         "udp",
         "any"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Protocol"
     },
     "sources": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Sources"
     }
    },
    "title": "FirewallRuleUpdate",
    "type": "object"
   },
   "FirstTimeSetupCheckResponse": {
    "properties": {
     "registration_open": {
      "default": false,
      "title": "Registration Open",
      "type": "boolean"
     },
     "setup_required": {
      "title": "Setup Required",
      "type": "boolean"
     },
     "username": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Username"
     }
    },
    "required": [
     "setup_required"
    ],
    "title": "FirstTimeSetupCheckResponse",
    "type": "object"
   },
   "FirstTimeSetupRequest": {
    "properties": {
     "password": {
      "minLength": 8,
      "title": "Password",
      "type": "string"
     },
     "setup_token": {
      "minLength": 8,
      "title": "Setup Token",
      "type": "string"
     },
     "username": {
      "title": "Username",
      "type": "string"
     }
    },
    "required": [
     "username",
     "password",
     "setup_token"
    ],
    "title": "FirstTimeSetupRequest",
    "type": "object"
   },
   "FirstTimeSetupResponse": {
    "properties": {
     "message": {
      "title": "Message",
      "type": "string"
     },
     "mfa_qr_uri": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Mfa Qr Uri"
     },
     "mfa_required": {
      "title": "Mfa Required",
      "type": "boolean"
     },
     "mfa_secret": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Mfa Secret"
     }
    },
    "required": [
     "message",
     "mfa_required"
    ],
    "title": "FirstTimeSetupResponse",
    "type": "object"
   },
   "HTTPValidationError": {
    "properties": {
     "detail": {
      "items": {
       "$ref": "#/components/schemas/ValidationError"
      },
      "title": "Detail",
      "type": "array"
     }
    },
    "title": "HTTPValidationError",
    "type": "object"
   },
   "ImagingUpdate": {
    "properties": {
     "backlight": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Backlight"
     },
     "brightness": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Brightness"
     },
     "contrast": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Contrast"
     },
     "flip": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Flip"
     },
     "ir_cut_filter": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Ir Cut Filter"
     },
     "noise_reduce_mode": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Noise Reduce Mode"
     },
     "noise_reduction": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Noise Reduction"
     },
     "saturation": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Saturation"
     },
     "sharpness": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Sharpness"
     },
     "wdr": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Wdr"
     }
    },
    "title": "ImagingUpdate",
    "type": "object"
   },
   "InferenceRequest": {
    "properties": {
     "camera_id": {
      "title": "Camera Id",
      "type": "integer"
     },
     "model_id": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Model Id"
     },
     "model_name": {
      "title": "Model Name",
      "type": "string"
     },
     "options": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "title": "Options"
     },
     "rtsp_url": {
      "title": "Rtsp Url",
      "type": "string"
     },
     "task": {
      "title": "Task",
      "type": "string"
     }
    },
    "required": [
     "camera_id",
     "rtsp_url",
     "model_name",
     "task"
    ],
    "title": "InferenceRequest",
    "type": "object"
   },
   "InferenceResponse": {
    "properties": {
     "camera_id": {
      "title": "Camera Id",
      "type": "integer"
     },
     "message": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Message"
     },
     "model_used": {
      "title": "Model Used",
      "type": "string"
     },
     "response": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "title": "Response"
     },
     "status": {
      "title": "Status",
      "type": "string"
     },
     "task": {
      "title": "Task",
      "type": "string"
     }
    },
    "required": [
     "status",
     "camera_id",
     "model_used",
     "task"
    ],
    "title": "InferenceResponse",
    "type": "object"
   },
   "IntegrationCreate": {
    "properties": {
     "config": {
      "additionalProperties": true,
      "title": "Config",
      "type": "object"
     },
     "enabled": {
      "default": true,
      "title": "Enabled",
      "type": "boolean"
     },
     "name": {
      "maxLength": 100,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "type": {
      "title": "Type",
      "type": "string"
     }
    },
    "required": [
     "name",
     "type",
     "config"
    ],
    "title": "IntegrationCreate",
    "type": "object"
   },
   "IntegrationRead": {
    "properties": {
     "config": {
      "additionalProperties": true,
      "title": "Config",
      "type": "object"
     },
     "created_at": {
      "format": "date-time",
      "title": "Created At",
      "type": "string"
     },
     "enabled": {
      "default": true,
      "title": "Enabled",
      "type": "boolean"
     },
     "id": {
      "title": "Id",
      "type": "integer"
     },
     "name": {
      "maxLength": 100,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "type": {
      "title": "Type",
      "type": "string"
     },
     "updated_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Updated At"
     }
    },
    "required": [
     "name",
     "type",
     "config",
     "id",
     "created_at"
    ],
    "title": "IntegrationRead",
    "type": "object"
   },
   "IntegrationUpdate": {
    "properties": {
     "config": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "title": "Config"
     },
     "enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Enabled"
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 100,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Name"
     }
    },
    "title": "IntegrationUpdate",
    "type": "object"
   },
   "IpFilterUpdate": {
    "properties": {
     "enabled": {
      "title": "Enabled",
      "type": "boolean"
     },
     "entries": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "title": "Entries"
     },
     "mode": {
      "default": "allow",
      "title": "Mode",
      "type": "string"
     }
    },
    "required": [
     "enabled"
    ],
    "title": "IpFilterUpdate",
    "type": "object"
   },
   "KaiCHealthResponse": {
    "properties": {
     "adapters": {
      "additionalProperties": true,
      "title": "Adapters",
      "type": "object"
     },
     "kai_c_status": {
      "title": "Kai C Status",
      "type": "string"
     },
     "message": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Message"
     }
    },
    "required": [
     "kai_c_status",
     "adapters"
    ],
    "title": "KaiCHealthResponse",
    "type": "object"
   },
   "LicenseIn": {
    "properties": {
     "license_key": {
      "title": "License Key",
      "type": "string"
     }
    },
    "required": [
     "license_key"
    ],
    "title": "LicenseIn",
    "type": "object"
   },
   "ManualSyncRequest": {
    "properties": {
     "timezone": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Timezone"
     }
    },
    "title": "ManualSyncRequest",
    "type": "object"
   },
   "MediaSourceSettingsUpdate": {
    "properties": {
     "audio_bitrate_kbps": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Audio Bitrate Kbps"
     },
     "cloud_recording_server_ip": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Cloud Recording Server Ip"
     },
     "hls_enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Hls Enabled"
     },
     "ll_hls_enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Ll Hls Enabled"
     },
     "max_fps": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Max Fps"
     },
     "mediamtx_admin_api": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Mediamtx Admin Api"
     },
     "mediamtx_admin_token": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Mediamtx Admin Token"
     },
     "mediamtx_base_url": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Mediamtx Base Url"
     },
     "mediamtx_path_mode": {
      "anyOf": [
       {
        "enum": [
         "id",
         "ip"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Mediamtx Path Mode"
     },
     "mediamtx_stream_prefix": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Mediamtx Stream Prefix"
     },
     "mediamtx_token": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Mediamtx Token"
     },
     "scale_height": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Scale Height"
     },
     "scale_width": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Scale Width"
     },
     "tls_ca_bundle_pem": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Tls Ca Bundle Pem"
     },
     "tls_cert_pem": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Tls Cert Pem"
     },
     "tls_key_pem": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Tls Key Pem"
     },
     "transcode_audio_codec": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Transcode Audio Codec"
     },
     "transcode_video_codec": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Transcode Video Codec"
     },
     "transcoding_enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Transcoding Enabled"
     },
     "uplink_streaming_server_ip": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Uplink Streaming Server Ip"
     },
     "video_bitrate_kbps": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Video Bitrate Kbps"
     }
    },
    "title": "MediaSourceSettingsUpdate",
    "type": "object"
   },
   "MfaSetupResponse": {
    "properties": {
     "otpauth_url": {
      "title": "Otpauth Url",
      "type": "string"
     },
     "secret": {
      "title": "Secret",
      "type": "string"
     }
    },
    "required": [
     "otpauth_url",
     "secret"
    ],
    "title": "MfaSetupResponse",
    "type": "object"
   },
   "MfaVerifyRequest": {
    "properties": {
     "code": {
      "maxLength": 8,
      "minLength": 6,
      "title": "Code",
      "type": "string"
     }
    },
    "required": [
     "code"
    ],
    "title": "MfaVerifyRequest",
    "type": "object"
   },
   "MotionUpdate": {
    "properties": {
     "enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Enabled"
     },
     "sensitivity": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Sensitivity"
     }
    },
    "title": "MotionUpdate",
    "type": "object"
   },
   "NetworkConfig": {
    "properties": {
     "alternate_dns": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Alternate Dns"
     },
     "blacklisted_ips": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "title": "Blacklisted Ips"
     },
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Description"
     },
     "dhcp_enabled": {
      "default": true,
      "title": "Dhcp Enabled",
      "type": "boolean"
     },
     "interface_name": {
      "title": "Interface Name",
      "type": "string"
     },
     "ipv4_address": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Ipv4 Address"
     },
     "ipv4_gateway": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Ipv4 Gateway"
     },
     "ipv4_subnet_mask": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Ipv4 Subnet Mask"
     },
     "mtu": {
      "default": 1500,
      "title": "Mtu",
      "type": "integer"
     },
     "preferred_dns": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Preferred Dns"
     },
     "scan_subnets": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "title": "Scan Subnets"
     },
     "subnet_cidr": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Subnet Cidr"
     }
    },
    "required": [
     "interface_name"
    ],
    "title": "NetworkConfig",
    "type": "object"
   },
   "NtpRequest": {
    "properties": {
     "server": {
      "title": "Server",
      "type": "string"
     },
     "timezone": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Timezone"
     }
    },
    "required": [
     "server"
    ],
    "title": "NtpRequest",
    "type": "object"
   },
   "OsdUpdate": {
    "properties": {
     "channel_name_enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Channel Name Enabled"
     },
     "datetime_enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Datetime Enabled"
     },
     "slots": {
      "anyOf": [
       {
        "items": {
         "additionalProperties": true,
         "type": "object"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "title": "Slots"
     },
     "text": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Text"
     },
     "text_enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Text Enabled"
     }
    },
    "title": "OsdUpdate",
    "type": "object"
   },
   "OverlayToggle": {
    "properties": {
     "enabled": {
      "title": "Enabled",
      "type": "boolean"
     }
    },
    "required": [
     "enabled"
    ],
    "title": "OverlayToggle",
    "type": "object"
   },
   "PasswordPolicyResponse": {
    "properties": {
     "created_at": {
      "format": "date-time",
      "title": "Created At",
      "type": "string"
     },
     "disallow_username_email": {
      "default": true,
      "title": "Disallow Username Email",
      "type": "boolean"
     },
     "expiration_days": {
      "anyOf": [
       {
        "maximum": 3650.0,
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Expiration Days"
     },
     "history_count": {
      "default": 5,
      "maximum": 50.0,
      "minimum": 0.0,
      "title": "History Count",
      "type": "integer"
     },
     "id": {
      "title": "Id",
      "type": "integer"
     },
     "lockout_minutes": {
      "default": 3,
      "maximum": 1440.0,
      "minimum": 0.0,
      "title": "Lockout Minutes",
      "type": "integer"
     },
     "max_failed_attempts": {
      "default": 5,
      "maximum": 50.0,
      "minimum": 0.0,
      "title": "Max Failed Attempts",
      "type": "integer"
     },
     "min_classes": {
      "default": 3,
      "maximum": 4.0,
      "minimum": 1.0,
      "title": "Min Classes",
      "type": "integer"
     },
     "min_length": {
      "default": 8,
      "maximum": 128.0,
      "minimum": 4.0,
      "title": "Min Length",
      "type": "integer"
     },
     "passphrase_enabled": {
      "default": true,
      "title": "Passphrase Enabled",
      "type": "boolean"
     },
     "passphrase_min_length": {
      "default": 16,
      "maximum": 256.0,
      "minimum": 8.0,
      "title": "Passphrase Min Length",
      "type": "integer"
     },
     "require_mfa_for_privileged": {
      "default": true,
      "title": "Require Mfa For Privileged",
      "type": "boolean"
     },
     "reset_token_ttl_minutes": {
      "default": 15,
      "maximum": 1440.0,
      "minimum": 1.0,
      "title": "Reset Token Ttl Minutes",
      "type": "integer"
     },
     "updated_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Updated At"
     }
    },
    "required": [
     "id",
     "created_at"
    ],
    "title": "PasswordPolicyResponse",
    "type": "object"
   },
   "PasswordPolicyUpdate": {
    "properties": {
     "disallow_username_email": {
      "default": true,
      "title": "Disallow Username Email",
      "type": "boolean"
     },
     "expiration_days": {
      "anyOf": [
       {
        "maximum": 3650.0,
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Expiration Days"
     },
     "history_count": {
      "default": 5,
      "maximum": 50.0,
      "minimum": 0.0,
      "title": "History Count",
      "type": "integer"
     },
     "lockout_minutes": {
      "default": 3,
      "maximum": 1440.0,
      "minimum": 0.0,
      "title": "Lockout Minutes",
      "type": "integer"
     },
     "max_failed_attempts": {
      "default": 5,
      "maximum": 50.0,
      "minimum": 0.0,
      "title": "Max Failed Attempts",
      "type": "integer"
     },
     "min_classes": {
      "default": 3,
      "maximum": 4.0,
      "minimum": 1.0,
      "title": "Min Classes",
      "type": "integer"
     },
     "min_length": {
      "default": 8,
      "maximum": 128.0,
      "minimum": 4.0,
      "title": "Min Length",
      "type": "integer"
     },
     "passphrase_enabled": {
      "default": true,
      "title": "Passphrase Enabled",
      "type": "boolean"
     },
     "passphrase_min_length": {
      "default": 16,
      "maximum": 256.0,
      "minimum": 8.0,
      "title": "Passphrase Min Length",
      "type": "integer"
     },
     "require_mfa_for_privileged": {
      "default": true,
      "title": "Require Mfa For Privileged",
      "type": "boolean"
     },
     "reset_token_ttl_minutes": {
      "default": 15,
      "maximum": 1440.0,
      "minimum": 1.0,
      "title": "Reset Token Ttl Minutes",
      "type": "integer"
     }
    },
    "title": "PasswordPolicyUpdate",
    "type": "object"
   },
   "PermissionCreate": {
    "description": "Schema for creating a new permission.",
    "properties": {
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Description"
     },
     "name": {
      "maxLength": 100,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     }
    },
    "required": [
     "name"
    ],
    "title": "PermissionCreate",
    "type": "object"
   },
   "PermissionKeysRequest": {
    "description": "Body for the grant / revoke permission endpoints.",
    "properties": {
     "keys": {
      "default": [],
      "items": {
       "type": "string"
      },
      "title": "Keys",
      "type": "array"
     }
    },
    "title": "PermissionKeysRequest",
    "type": "object"
   },
   "PermissionList": {
    "properties": {
     "permissions": {
      "items": {
       "$ref": "#/components/schemas/PermissionResponse"
      },
      "title": "Permissions",
      "type": "array"
     },
     "total": {
      "title": "Total",
      "type": "integer"
     }
    },
    "required": [
     "permissions",
     "total"
    ],
    "title": "PermissionList",
    "type": "object"
   },
   "PermissionResponse": {
    "properties": {
     "created_at": {
      "format": "date-time",
      "title": "Created At",
      "type": "string"
     },
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Description"
     },
     "id": {
      "title": "Id",
      "type": "integer"
     },
     "name": {
      "maxLength": 100,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "updated_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Updated At"
     }
    },
    "required": [
     "name",
     "id",
     "created_at"
    ],
    "title": "PermissionResponse",
    "type": "object"
   },
   "PermissionUpdate": {
    "description": "Schema for updating a permission.",
    "properties": {
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Description"
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 100,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Name"
     }
    },
    "title": "PermissionUpdate",
    "type": "object"
   },
   "PlateAttemptIn": {
    "description": "One early OCR attempt from Tier-0 \u2014 a plate candidate crop for a\nvehicle whose track just confirmed (multi-frame OCR, latency half).",
    "properties": {
     "camera_id": {
      "title": "Camera Id",
      "type": "integer"
     },
     "jpeg_b64": {
      "title": "Jpeg B64",
      "type": "string"
     },
     "track_id": {
      "title": "Track Id",
      "type": "string"
     },
     "ts": {
      "title": "Ts",
      "type": "number"
     }
    },
    "required": [
     "camera_id",
     "track_id",
     "ts",
     "jpeg_b64"
    ],
    "title": "PlateAttemptIn",
    "type": "object"
   },
   "ProvisionResult": {
    "description": "Response for provisioning to MediaMTX.",
    "properties": {
     "camera_id": {
      "title": "Camera Id",
      "type": "integer"
     },
     "details": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "title": "Details"
     },
     "path": {
      "title": "Path",
      "type": "string"
     },
     "status": {
      "title": "Status",
      "type": "string"
     }
    },
    "required": [
     "camera_id",
     "path",
     "status"
    ],
    "title": "ProvisionResult",
    "type": "object"
   },
   "RecordingInferenceRequest": {
    "properties": {
     "camera_id": {
      "title": "Camera Id",
      "type": "integer"
     },
     "end_time": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "End Time"
     },
     "frame_interval": {
      "default": 30,
      "title": "Frame Interval",
      "type": "integer"
     },
     "model_id": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Model Id"
     },
     "model_name": {
      "title": "Model Name",
      "type": "string"
     },
     "options": {
      "anyOf": [
       {
        "additionalProperties": true,
        "type": "object"
       },
       {
        "type": "null"
       }
      ],
      "title": "Options"
     },
     "recording_path": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Recording Path"
     },
     "segments": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "title": "Segments"
     },
     "session_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Session Id"
     },
     "start_time": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Start Time"
     },
     "task": {
      "title": "Task",
      "type": "string"
     }
    },
    "required": [
     "camera_id",
     "model_name",
     "task"
    ],
    "title": "RecordingInferenceRequest",
    "type": "object"
   },
   "RecordingRetentionSettings": {
    "properties": {
     "min_free_space_gb": {
      "anyOf": [
       {
        "maximum": 100000.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Min Free Space Gb"
     },
     "protect_flagged": {
      "default": true,
      "title": "Protect Flagged",
      "type": "boolean"
     },
     "purge_orphaned_under_pressure": {
      "default": false,
      "title": "Purge Orphaned Under Pressure",
      "type": "boolean"
     },
     "retention_days": {
      "anyOf": [
       {
        "maximum": 3650.0,
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "default": 30,
      "title": "Retention Days"
     }
    },
    "title": "RecordingRetentionSettings",
    "type": "object"
   },
   "RecordingScheduleSettings": {
    "properties": {
     "mode": {
      "default": "continuous",
      "enum": [
       "continuous",
       "motion",
       "schedule"
      ],
      "title": "Mode",
      "type": "string"
     },
     "windows": {
      "default": [],
      "items": {
       "$ref": "#/components/schemas/RecordingScheduleWindow"
      },
      "title": "Windows",
      "type": "array"
     }
    },
    "title": "RecordingScheduleSettings",
    "type": "object"
   },
   "RecordingScheduleWindow": {
    "properties": {
     "day": {
      "maximum": 6.0,
      "minimum": 0.0,
      "title": "Day",
      "type": "integer"
     },
     "end": {
      "pattern": "^\\d{2}:\\d{2}$",
      "title": "End",
      "type": "string"
     },
     "start": {
      "pattern": "^\\d{2}:\\d{2}$",
      "title": "Start",
      "type": "string"
     }
    },
    "required": [
     "day",
     "start",
     "end"
    ],
    "title": "RecordingScheduleWindow",
    "type": "object"
   },
   "RecordingStorageSettings": {
    "properties": {
     "active_device_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Active Device Id"
     },
     "devices": {
      "default": [],
      "items": {
       "$ref": "#/components/schemas/StorageDevice"
      },
      "title": "Devices",
      "type": "array"
     },
     "filename_template": {
      "default": "%camera/%Y/%m/%d/%H/%M/%S.mp4",
      "minLength": 1,
      "title": "Filename Template",
      "type": "string"
     },
     "max_storage_gb": {
      "anyOf": [
       {
        "maximum": 100000.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Max Storage Gb"
     },
     "min_free_space_gb": {
      "anyOf": [
       {
        "maximum": 100000.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Min Free Space Gb"
     },
     "recordings_base_path": {
      "anyOf": [
       {
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Recordings Base Path"
     },
     "segment_seconds": {
      "default": 60,
      "maximum": 3600.0,
      "minimum": 5.0,
      "title": "Segment Seconds",
      "type": "integer"
     }
    },
    "title": "RecordingStorageSettings",
    "type": "object"
   },
   "RingConfigIn": {
    "properties": {
     "ring": {
      "additionalProperties": {
       "type": "string"
      },
      "title": "Ring",
      "type": "object"
     }
    },
    "required": [
     "ring"
    ],
    "title": "RingConfigIn",
    "type": "object"
   },
   "RoleCreate": {
    "description": "Schema for creating a new role.",
    "properties": {
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Description"
     },
     "name": {
      "maxLength": 50,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     }
    },
    "required": [
     "name"
    ],
    "title": "RoleCreate",
    "type": "object"
   },
   "RoleList": {
    "properties": {
     "roles": {
      "items": {
       "$ref": "#/components/schemas/RoleResponse"
      },
      "title": "Roles",
      "type": "array"
     },
     "total": {
      "title": "Total",
      "type": "integer"
     }
    },
    "required": [
     "roles",
     "total"
    ],
    "title": "RoleList",
    "type": "object"
   },
   "RolePermissionsSet": {
    "description": "Schema to set permissions for a role (replace assignment).",
    "properties": {
     "permission_ids": {
      "items": {
       "type": "integer"
      },
      "title": "Permission Ids",
      "type": "array"
     }
    },
    "required": [
     "permission_ids"
    ],
    "title": "RolePermissionsSet",
    "type": "object"
   },
   "RoleResponse": {
    "properties": {
     "created_at": {
      "format": "date-time",
      "title": "Created At",
      "type": "string"
     },
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Description"
     },
     "id": {
      "title": "Id",
      "type": "integer"
     },
     "name": {
      "maxLength": 50,
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "updated_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Updated At"
     }
    },
    "required": [
     "name",
     "id",
     "created_at"
    ],
    "title": "RoleResponse",
    "type": "object"
   },
   "RoleUpdate": {
    "description": "Schema for updating a role.",
    "properties": {
     "description": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Description"
     },
     "name": {
      "anyOf": [
       {
        "maxLength": 50,
        "minLength": 1,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Name"
     }
    },
    "title": "RoleUpdate",
    "type": "object"
   },
   "SecuritySettingPayload": {
    "properties": {
     "key": {
      "title": "Key",
      "type": "string"
     },
     "value": {
      "additionalProperties": true,
      "title": "Value",
      "type": "object"
     }
    },
    "required": [
     "key",
     "value"
    ],
    "title": "SecuritySettingPayload",
    "type": "object"
   },
   "SecuritySettingResponse": {
    "properties": {
     "key": {
      "title": "Key",
      "type": "string"
     },
     "value": {
      "additionalProperties": true,
      "title": "Value",
      "type": "object"
     }
    },
    "required": [
     "key",
     "value"
    ],
    "title": "SecuritySettingResponse",
    "type": "object"
   },
   "ServiceUpdate": {
    "properties": {
     "enabled": {
      "title": "Enabled",
      "type": "boolean"
     }
    },
    "required": [
     "enabled"
    ],
    "title": "ServiceUpdate",
    "type": "object"
   },
   "SmartUpdate": {
    "properties": {
     "enabled": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Enabled"
     },
     "sensitivity": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Sensitivity"
     }
    },
    "title": "SmartUpdate",
    "type": "object"
   },
   "StorageDevice": {
    "properties": {
     "enabled": {
      "default": true,
      "title": "Enabled",
      "type": "boolean"
     },
     "id": {
      "minLength": 1,
      "title": "Id",
      "type": "string"
     },
     "mount_path": {
      "minLength": 1,
      "title": "Mount Path",
      "type": "string"
     },
     "name": {
      "minLength": 1,
      "title": "Name",
      "type": "string"
     },
     "quota_gb": {
      "anyOf": [
       {
        "maximum": 1000000.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Quota Gb"
     },
     "type": {
      "default": "hdd",
      "enum": [
       "hdd",
       "ssd",
       "usb",
       "nas"
      ],
      "title": "Type",
      "type": "string"
     }
    },
    "required": [
     "id",
     "name",
     "mount_path"
    ],
    "title": "StorageDevice",
    "type": "object"
   },
   "SystemMonitoringSettings": {
    "description": "Host resource monitoring + alert thresholds (security_settings key\n``system_monitoring``). None disables the individual threshold.",
    "properties": {
     "cpu_percent_threshold": {
      "anyOf": [
       {
        "maximum": 100.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "default": 90,
      "title": "Cpu Percent Threshold"
     },
     "disk_min_free_gb": {
      "anyOf": [
       {
        "minimum": 1.0,
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "title": "Disk Min Free Gb"
     },
     "disk_used_percent_threshold": {
      "anyOf": [
       {
        "maximum": 100.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "default": 90,
      "title": "Disk Used Percent Threshold"
     },
     "enabled": {
      "default": true,
      "title": "Enabled",
      "type": "boolean"
     },
     "memory_percent_threshold": {
      "anyOf": [
       {
        "maximum": 100.0,
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "default": 90,
      "title": "Memory Percent Threshold"
     },
     "notify_integrations": {
      "default": false,
      "title": "Notify Integrations",
      "type": "boolean"
     },
     "renotify_cooldown_minutes": {
      "default": 60,
      "minimum": 0.0,
      "title": "Renotify Cooldown Minutes",
      "type": "integer"
     },
     "resolve_hysteresis_percent": {
      "default": 5,
      "maximum": 20.0,
      "minimum": 1.0,
      "title": "Resolve Hysteresis Percent",
      "type": "integer"
     },
     "sustained_seconds": {
      "default": 120,
      "maximum": 3600.0,
      "minimum": 15.0,
      "title": "Sustained Seconds",
      "type": "integer"
     }
    },
    "title": "SystemMonitoringSettings",
    "type": "object"
   },
   "TaskEntry": {
    "description": "One canonical task in the curated taxonomy (server/config/tasks.yml).\n\n``task`` is the canonical string an adapter SHOULD advertise in\n``tasks_advertised`` (contract \u00a74). ``aliases`` are non-canonical\nspellings that mean the same capability \u2014 the canonicalizer folds\nthem in, and the OpenNVR Agent's skill mapping treats an adapter\nadvertising an alias exactly like the canonical. ``agent_skill`` names\nthe Agent skill id (see/count/faces/watch) this task backs, or None.\n``suggested_adapters`` names the reference adapter(s) that provide this\ntask (editorial, consistent with ``use_case_map.yml``) \u2014 the OpenNVR\nAgent surfaces these to guide an operator to enable one when a skill is\ngreyed out.",
    "properties": {
     "agent_skill": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Agent Skill"
     },
     "aliases": {
      "default": [],
      "items": {
       "type": "string"
      },
      "title": "Aliases",
      "type": "array"
     },
     "categories": {
      "default": [],
      "items": {
       "type": "string"
      },
      "title": "Categories",
      "type": "array"
     },
     "label": {
      "title": "Label",
      "type": "string"
     },
     "suggested_adapters": {
      "default": [],
      "items": {
       "type": "string"
      },
      "title": "Suggested Adapters",
      "type": "array"
     },
     "suggested_apps": {
      "default": [],
      "items": {
       "type": "string"
      },
      "title": "Suggested Apps",
      "type": "array"
     },
     "summary": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Summary"
     },
     "tags": {
      "default": [],
      "items": {
       "type": "string"
      },
      "title": "Tags",
      "type": "array"
     },
     "task": {
      "title": "Task",
      "type": "string"
     }
    },
    "required": [
     "task",
     "label"
    ],
    "title": "TaskEntry",
    "type": "object"
   },
   "TenantQuotaResponse": {
    "description": "Schema for tenant quota response.",
    "properties": {
     "circuit_failure_count": {
      "title": "Circuit Failure Count",
      "type": "integer"
     },
     "circuit_state": {
      "title": "Circuit State",
      "type": "string"
     },
     "concurrent_limit": {
      "title": "Concurrent Limit",
      "type": "integer"
     },
     "concurrent_usage": {
      "title": "Concurrent Usage",
      "type": "integer"
     },
     "daily_quota": {
      "title": "Daily Quota",
      "type": "integer"
     },
     "daily_remaining": {
      "title": "Daily Remaining",
      "type": "integer"
     },
     "daily_usage": {
      "title": "Daily Usage",
      "type": "integer"
     },
     "monthly_quota": {
      "title": "Monthly Quota",
      "type": "integer"
     },
     "monthly_remaining": {
      "title": "Monthly Remaining",
      "type": "integer"
     },
     "monthly_usage": {
      "title": "Monthly Usage",
      "type": "integer"
     },
     "provider": {
      "title": "Provider",
      "type": "string"
     }
    },
    "required": [
     "provider",
     "daily_usage",
     "daily_quota",
     "daily_remaining",
     "monthly_usage",
     "monthly_quota",
     "monthly_remaining",
     "concurrent_usage",
     "concurrent_limit",
     "circuit_state",
     "circuit_failure_count"
    ],
    "title": "TenantQuotaResponse",
    "type": "object"
   },
   "TenantQuotaUpdate": {
    "description": "Schema for updating tenant quotas.",
    "properties": {
     "concurrent_limit": {
      "anyOf": [
       {
        "minimum": 1.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Concurrent Limit"
     },
     "daily_quota": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Daily Quota"
     },
     "monthly_quota": {
      "anyOf": [
       {
        "minimum": 0.0,
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Monthly Quota"
     }
    },
    "title": "TenantQuotaUpdate",
    "type": "object"
   },
   "TestAlarmIn": {
    "properties": {
     "severity": {
      "default": "high",
      "title": "Severity",
      "type": "string"
     }
    },
    "title": "TestAlarmIn",
    "type": "object"
   },
   "Tier0GateUpdate": {
    "properties": {
     "mode": {
      "title": "Mode",
      "type": "string"
     }
    },
    "required": [
     "mode"
    ],
    "title": "Tier0GateUpdate",
    "type": "object"
   },
   "Token": {
    "properties": {
     "access_token": {
      "title": "Access Token",
      "type": "string"
     },
     "device_token": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Device Token"
     },
     "refresh_token": {
      "title": "Refresh Token",
      "type": "string"
     },
     "token_type": {
      "title": "Token Type",
      "type": "string"
     }
    },
    "required": [
     "access_token",
     "refresh_token",
     "token_type"
    ],
    "title": "Token",
    "type": "object"
   },
   "TrackEventIn": {
    "description": "One finished object visit, posted by the detect-pipeline at track end.",
    "properties": {
     "camera_id": {
      "title": "Camera Id",
      "type": "integer"
     },
     "candidate_jpegs_b64": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "title": "Candidate Jpegs B64"
     },
     "candidate_ts": {
      "anyOf": [
       {
        "items": {
         "type": "number"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "title": "Candidate Ts"
     },
     "ended_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Ended At"
     },
     "evidence_jpeg_b64": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Evidence Jpeg B64"
     },
     "evidence_ts": {
      "anyOf": [
       {
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "title": "Evidence Ts"
     },
     "label": {
      "title": "Label",
      "type": "string"
     },
     "scene_jpeg_b64": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Scene Jpeg B64"
     },
     "score": {
      "anyOf": [
       {
        "type": "number"
       },
       {
        "type": "null"
       }
      ],
      "title": "Score"
     },
     "started_at": {
      "format": "date-time",
      "title": "Started At",
      "type": "string"
     },
     "stationary": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Stationary"
     },
     "track_id": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Track Id"
     }
    },
    "required": [
     "camera_id",
     "label",
     "started_at"
    ],
    "title": "TrackEventIn",
    "type": "object"
   },
   "TransportSecurityUpdate": {
    "description": "Explicit operator override for a camera's transport policy.",
    "properties": {
     "policy": {
      "pattern": "^(rtsps_required|rtsps_preferred|plaintext_allowed)$",
      "title": "Policy",
      "type": "string"
     }
    },
    "required": [
     "policy"
    ],
    "title": "TransportSecurityUpdate",
    "type": "object"
   },
   "TurnServer": {
    "properties": {
     "credential": {
      "anyOf": [
       {
        "maxLength": 255,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Credential"
     },
     "url": {
      "maxLength": 255,
      "minLength": 3,
      "title": "Url",
      "type": "string"
     },
     "username": {
      "anyOf": [
       {
        "maxLength": 255,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Username"
     }
    },
    "required": [
     "url"
    ],
    "title": "TurnServer",
    "type": "object"
   },
   "UseCaseEntry": {
    "properties": {
     "also_needs": {
      "default": [],
      "items": {
       "type": "string"
      },
      "title": "Also Needs",
      "type": "array"
     },
     "intent": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Intent"
     },
     "needs_capability": {
      "title": "Needs Capability",
      "type": "string"
     },
     "suggested_adapters": {
      "default": [],
      "items": {
       "type": "string"
      },
      "title": "Suggested Adapters",
      "type": "array"
     },
     "suggested_apps": {
      "default": [],
      "items": {
       "type": "string"
      },
      "title": "Suggested Apps",
      "type": "array"
     },
     "use_case": {
      "title": "Use Case",
      "type": "string"
     }
    },
    "required": [
     "use_case",
     "needs_capability"
    ],
    "title": "UseCaseEntry",
    "type": "object"
   },
   "UserCreate": {
    "description": "Schema for creating a new user.",
    "properties": {
     "email": {
      "format": "email",
      "title": "Email",
      "type": "string"
     },
     "first_name": {
      "anyOf": [
       {
        "maxLength": 50,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "First Name"
     },
     "is_active": {
      "default": true,
      "title": "Is Active",
      "type": "boolean"
     },
     "is_superuser": {
      "default": false,
      "title": "Is Superuser",
      "type": "boolean"
     },
     "last_name": {
      "anyOf": [
       {
        "maxLength": 50,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Last Name"
     },
     "password": {
      "minLength": 8,
      "title": "Password",
      "type": "string"
     },
     "role_id": {
      "title": "Role Id",
      "type": "integer"
     },
     "username": {
      "maxLength": 50,
      "minLength": 3,
      "title": "Username",
      "type": "string"
     }
    },
    "required": [
     "username",
     "email",
     "password",
     "role_id"
    ],
    "title": "UserCreate",
    "type": "object"
   },
   "UserList": {
    "properties": {
     "total": {
      "title": "Total",
      "type": "integer"
     },
     "users": {
      "items": {
       "$ref": "#/components/schemas/UserResponse"
      },
      "title": "Users",
      "type": "array"
     }
    },
    "required": [
     "users",
     "total"
    ],
    "title": "UserList",
    "type": "object"
   },
   "UserLogin": {
    "properties": {
     "code": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Code"
     },
     "password": {
      "title": "Password",
      "type": "string"
     },
     "username": {
      "title": "Username",
      "type": "string"
     }
    },
    "required": [
     "username",
     "password"
    ],
    "title": "UserLogin",
    "type": "object"
   },
   "UserRegister": {
    "description": "Public registration schema.",
    "properties": {
     "email": {
      "format": "email",
      "title": "Email",
      "type": "string"
     },
     "password": {
      "minLength": 8,
      "title": "Password",
      "type": "string"
     },
     "username": {
      "maxLength": 50,
      "minLength": 3,
      "title": "Username",
      "type": "string"
     }
    },
    "required": [
     "username",
     "email",
     "password"
    ],
    "title": "UserRegister",
    "type": "object"
   },
   "UserResponse": {
    "properties": {
     "created_at": {
      "format": "date-time",
      "title": "Created At",
      "type": "string"
     },
     "email": {
      "title": "Email",
      "type": "string"
     },
     "first_name": {
      "anyOf": [
       {
        "maxLength": 50,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "First Name"
     },
     "id": {
      "title": "Id",
      "type": "integer"
     },
     "is_active": {
      "default": true,
      "title": "Is Active",
      "type": "boolean"
     },
     "is_superuser": {
      "title": "Is Superuser",
      "type": "boolean"
     },
     "last_name": {
      "anyOf": [
       {
        "maxLength": 50,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Last Name"
     },
     "mfa_enabled": {
      "title": "Mfa Enabled",
      "type": "boolean"
     },
     "password_set": {
      "title": "Password Set",
      "type": "boolean"
     },
     "role_id": {
      "title": "Role Id",
      "type": "integer"
     },
     "role_name": {
      "anyOf": [
       {
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Role Name"
     },
     "updated_at": {
      "anyOf": [
       {
        "format": "date-time",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Updated At"
     },
     "username": {
      "maxLength": 50,
      "minLength": 3,
      "title": "Username",
      "type": "string"
     }
    },
    "required": [
     "username",
     "email",
     "id",
     "role_id",
     "is_superuser",
     "password_set",
     "mfa_enabled",
     "created_at"
    ],
    "title": "UserResponse",
    "type": "object"
   },
   "UserUpdate": {
    "description": "Schema for updating a user.",
    "properties": {
     "email": {
      "anyOf": [
       {
        "format": "email",
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Email"
     },
     "first_name": {
      "anyOf": [
       {
        "maxLength": 50,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "First Name"
     },
     "is_active": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Is Active"
     },
     "is_superuser": {
      "anyOf": [
       {
        "type": "boolean"
       },
       {
        "type": "null"
       }
      ],
      "title": "Is Superuser"
     },
     "last_name": {
      "anyOf": [
       {
        "maxLength": 50,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Last Name"
     },
     "role_id": {
      "anyOf": [
       {
        "type": "integer"
       },
       {
        "type": "null"
       }
      ],
      "title": "Role Id"
     },
     "username": {
      "anyOf": [
       {
        "maxLength": 50,
        "minLength": 3,
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Username"
     }
    },
    "title": "UserUpdate",
    "type": "object"
   },
   "ValidationError": {
    "properties": {
     "ctx": {
      "title": "Context",
      "type": "object"
     },
     "input": {
      "title": "Input"
     },
     "loc": {
      "items": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "integer"
        }
       ]
      },
      "title": "Location",
      "type": "array"
     },
     "msg": {
      "title": "Message",
      "type": "string"
     },
     "type": {
      "title": "Error Type",
      "type": "string"
     }
    },
    "required": [
     "loc",
     "msg",
     "type"
    ],
    "title": "ValidationError",
    "type": "object"
   },
   "WebRTCClientConfig": {
    "description": "Client-friendly config for RTCPeerConnection init.",
    "properties": {
     "iceServers": {
      "items": {
       "additionalProperties": true,
       "type": "object"
      },
      "title": "Iceservers",
      "type": "array"
     },
     "iceTransportPolicy": {
      "enum": [
       "all",
       "relay"
      ],
      "title": "Icetransportpolicy",
      "type": "string"
     }
    },
    "required": [
     "iceServers",
     "iceTransportPolicy"
    ],
    "title": "WebRTCClientConfig",
    "type": "object"
   },
   "WebRTCSettingsUpdate": {
    "properties": {
     "stun_servers": {
      "anyOf": [
       {
        "items": {
         "type": "string"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "title": "Stun Servers"
     },
     "transport_policy": {
      "anyOf": [
       {
        "enum": [
         "all",
         "relay"
        ],
        "type": "string"
       },
       {
        "type": "null"
       }
      ],
      "title": "Transport Policy"
     },
     "turn_servers": {
      "anyOf": [
       {
        "items": {
         "$ref": "#/components/schemas/TurnServer"
        },
        "type": "array"
       },
       {
        "type": "null"
       }
      ],
      "title": "Turn Servers"
     }
    },
    "title": "WebRTCSettingsUpdate",
    "type": "object"
   },
   "WindowDivisionSettings": {
    "properties": {
     "custom_layouts": {
      "default": [],
      "items": {
       "$ref": "#/components/schemas/CustomWindowLayout"
      },
      "title": "Custom Layouts",
      "type": "array"
     },
     "default_layout": {
      "default": "2x2",
      "title": "Default Layout",
      "type": "string"
     },
     "layouts_enabled": {
      "additionalProperties": {
       "type": "boolean"
      },
      "default": {
       "1+1+10": true,
       "1+12": true,
       "1+5": true,
       "1+7": true,
       "1x1": true,
       "2+8": true,
       "2x2": true,
       "3x3": true,
       "4+9": true,
       "4x4": true
      },
      "title": "Layouts Enabled",
      "type": "object"
     }
    },
    "title": "WindowDivisionSettings",
    "type": "object"
   }
  },
  "securitySchemes": {
   "HTTPBearer": {
    "scheme": "bearer",
    "type": "http"
   }
  }
 },
 "info": {
  "description": "A comprehensive surveillance system API with user management, camera control, and recording management",
  "title": "OpenNVR Surveillance System API",
  "version": "0.1.5"
 },
 "openapi": "3.1.0",
 "paths": {
  "/.well-known/jwks.json": {
   "get": {
    "description": "JWKS (JSON Web Key Set) endpoint for MediaMTX JWT authentication.\n\nMediaMTX fetches public keys from this endpoint to validate JWTs.\nThis enables the backend to be the sole authority for stream access.",
    "operationId": "get_jwks__well_known_jwks_json_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Get Jwks"
   }
  },
  "/api/v1/adapters/index": {
   "get": {
    "description": "The adapter catalog \u2014 every model a deployment can install.\n\n``?task=`` narrows to the adapters that satisfy one task convention,\nwhich is the question an operator actually has: *what can read\nplates on this deployment, and what would I be trading?*\n\nThe response groups by task as well as listing the adapters, so the\nUI can show the choices for a capability side by side. Nothing here\ncontacts an adapter; it is the curated index, not a live probe \u2014\n``GET /api/v1/ai-models/adapters-metrics`` is the live view of what\nis actually registered and running.",
    "operationId": "get_adapters_index_api_v1_adapters_index_get",
    "parameters": [
     {
      "in": "query",
      "name": "task",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Task"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Adapters Index Api V1 Adapters Index Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Adapters Index",
    "tags": [
     "adapters"
    ]
   }
  },
  "/api/v1/ai-detection-results": {
   "get": {
    "description": "Get detection results with optional filters.",
    "operationId": "get_detection_results_api_v1_ai_detection_results_get",
    "parameters": [
     {
      "in": "query",
      "name": "skip",
      "required": false,
      "schema": {
       "default": 0,
       "minimum": 0,
       "title": "Skip",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 100,
       "maximum": 500,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "model_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Model Id"
      }
     },
     {
      "in": "query",
      "name": "camera_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Camera Id"
      }
     },
     {
      "in": "query",
      "name": "task",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Task"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "$ref": "#/components/schemas/AIDetectionResultResponse"
         },
         "title": "Response Get Detection Results Api V1 Ai Detection Results Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Detection Results",
    "tags": [
     "ai-detection-results"
    ]
   },
   "post": {
    "description": "Store a detection result.",
    "operationId": "create_detection_result_api_v1_ai_detection_results_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AIDetectionResultCreate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AIDetectionResultResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create Detection Result",
    "tags": [
     "ai-detection-results"
    ]
   }
  },
  "/api/v1/ai-detection-results/bulk/older-than/{days}": {
   "delete": {
    "description": "Delete detection results older than specified days.",
    "operationId": "delete_old_results_api_v1_ai_detection_results_bulk_older_than__days__delete",
    "parameters": [
     {
      "in": "path",
      "name": "days",
      "required": true,
      "schema": {
       "title": "Days",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete Old Results",
    "tags": [
     "ai-detection-results"
    ]
   }
  },
  "/api/v1/ai-detection-results/{result_id}": {
   "delete": {
    "description": "Delete a detection result.",
    "operationId": "delete_detection_result_api_v1_ai_detection_results__result_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "result_id",
      "required": true,
      "schema": {
       "title": "Result Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete Detection Result",
    "tags": [
     "ai-detection-results"
    ]
   },
   "get": {
    "description": "Get a specific detection result by ID.",
    "operationId": "get_detection_result_api_v1_ai_detection_results__result_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "result_id",
      "required": true,
      "schema": {
       "title": "Result Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AIDetectionResultResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Detection Result",
    "tags": [
     "ai-detection-results"
    ]
   }
  },
  "/api/v1/ai-model-management": {
   "get": {
    "description": "Get all AI model configurations.",
    "operationId": "get_ai_models_api_v1_ai_model_management_get",
    "parameters": [
     {
      "in": "query",
      "name": "skip",
      "required": false,
      "schema": {
       "default": 0,
       "minimum": 0,
       "title": "Skip",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 100,
       "maximum": 500,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "enabled_only",
      "required": false,
      "schema": {
       "default": false,
       "title": "Enabled Only",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "$ref": "#/components/schemas/AIModelResponse"
         },
         "title": "Response Get Ai Models Api V1 Ai Model Management Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Ai Models",
    "tags": [
     "ai-model-management"
    ]
   },
   "post": {
    "description": "Create a new AI model configuration.",
    "operationId": "create_ai_model_api_v1_ai_model_management_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AIModelCreate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AIModelResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create Ai Model",
    "tags": [
     "ai-model-management"
    ]
   }
  },
  "/api/v1/ai-model-management/inference/running": {
   "get": {
    "description": "Get all models with running inference.",
    "operationId": "get_running_inference_api_v1_ai_model_management_inference_running_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Running Inference",
    "tags": [
     "ai-model-management"
    ]
   }
  },
  "/api/v1/ai-model-management/recording-sessions": {
   "get": {
    "description": "List available recording sessions grouped by camera and date.\nReturns hierarchical structure: camera -> date -> sessions.\nEach session contains one or more continuous recording segments.",
    "operationId": "list_recording_sessions_for_ai_api_v1_ai_model_management_recording_sessions_get",
    "parameters": [
     {
      "description": "Filter by camera ID",
      "in": "query",
      "name": "camera_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "description": "Filter by camera ID",
       "title": "Camera Id"
      }
     },
     {
      "description": "Filter by date (YYYY-MM-DD)",
      "in": "query",
      "name": "date",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Filter by date (YYYY-MM-DD)",
       "title": "Date"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Recording Sessions For Ai",
    "tags": [
     "ai-model-management"
    ]
   }
  },
  "/api/v1/ai-model-management/recordings": {
   "get": {
    "description": "List available recordings that can be used for AI processing.\nReturns recordings with camera info, duration, and file paths.\n\nDEPRECATED: Use /recording-sessions for better grouped view.",
    "operationId": "list_recordings_for_ai_api_v1_ai_model_management_recordings_get",
    "parameters": [
     {
      "description": "Filter by camera ID",
      "in": "query",
      "name": "camera_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "description": "Filter by camera ID",
       "title": "Camera Id"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 100,
       "maximum": 500,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "offset",
      "required": false,
      "schema": {
       "default": 0,
       "minimum": 0,
       "title": "Offset",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Recordings For Ai",
    "tags": [
     "ai-model-management"
    ]
   }
  },
  "/api/v1/ai-model-management/{model_id}": {
   "delete": {
    "description": "Delete an AI model configuration.",
    "operationId": "delete_ai_model_api_v1_ai_model_management__model_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete Ai Model",
    "tags": [
     "ai-model-management"
    ]
   },
   "get": {
    "description": "Get a specific AI model by ID.",
    "operationId": "get_ai_model_api_v1_ai_model_management__model_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AIModelResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Ai Model",
    "tags": [
     "ai-model-management"
    ]
   },
   "put": {
    "description": "Update an AI model configuration.",
    "operationId": "update_ai_model_api_v1_ai_model_management__model_id__put",
    "parameters": [
     {
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AIModelUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AIModelResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Ai Model",
    "tags": [
     "ai-model-management"
    ]
   }
  },
  "/api/v1/ai-model-management/{model_id}/inference-status": {
   "get": {
    "description": "Get inference status for a model.",
    "operationId": "get_inference_status_api_v1_ai_model_management__model_id__inference_status_get",
    "parameters": [
     {
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Inference Status",
    "tags": [
     "ai-model-management"
    ]
   }
  },
  "/api/v1/ai-model-management/{model_id}/start-inference": {
   "post": {
    "description": "RETIRED: returns 410 Gone with the migration pointer.\n\nKept as an endpoint (rather than deleted) so an older UI or script gets\nan actionable sentence instead of a bare 404.",
    "operationId": "start_inference_api_v1_ai_model_management__model_id__start_inference_post",
    "parameters": [
     {
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Start Inference",
    "tags": [
     "ai-model-management"
    ]
   }
  },
  "/api/v1/ai-model-management/{model_id}/stop-inference": {
   "post": {
    "description": "Stop background inference for a model.",
    "operationId": "stop_inference_api_v1_ai_model_management__model_id__stop_inference_post",
    "parameters": [
     {
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Stop Inference",
    "tags": [
     "ai-model-management"
    ]
   }
  },
  "/api/v1/ai-models/adapters-metrics": {
   "get": {
    "description": "Every adapter's windowed rollup in one call \u2014 the AI Adapters\npage's fleet strip (N ok / worst p95 / total rpm) reads this.",
    "operationId": "get_fleet_metrics_api_v1_ai_models_adapters_metrics_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Fleet Metrics",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/ai-models/adapters/{adapter_name}/metrics": {
   "get": {
    "description": "Fetch the windowed per-adapter metrics rollup from KAI-C\n(observability spec \u00a705): p50/p95/p99 latency, outcome counts,\nsaturation gauges, and the fingerprint-change timeline.\n\nKAI-C collects these from each adapter's /metrics on its existing\n60s registry poll; users never talk to adapters directly.\n\nRequires authenticated user.",
    "operationId": "get_adapter_metrics_api_v1_ai_models_adapters__adapter_name__metrics_get",
    "parameters": [
     {
      "in": "path",
      "name": "adapter_name",
      "required": true,
      "schema": {
       "title": "Adapter Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Adapter Metrics",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/ai-models/adapters/{adapter_name}/permissions": {
   "get": {
    "description": "Fetch the permission-approval view for one adapter (\u00a78 / \u00a711):\ndeclared permission keys with labels + sovereignty-conflict flags,\nthe granted set, the still-pending set, and the derived\napproval_status. Read-only \u2014 no audit log.\n\nRequires authenticated user.",
    "operationId": "get_adapter_permissions_api_v1_ai_models_adapters__adapter_name__permissions_get",
    "parameters": [
     {
      "in": "path",
      "name": "adapter_name",
      "required": true,
      "schema": {
       "title": "Adapter Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Adapter Permissions",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/ai-models/adapters/{adapter_name}/permissions/approve-all": {
   "post": {
    "description": "Grant every declared permission key for an adapter \u2014 the operator\n\"approve\" button (\u00a78 / \u00a711). Writes an audit log.\n\nRequires authenticated user.",
    "operationId": "approve_all_adapter_permissions_api_v1_ai_models_adapters__adapter_name__permissions_approve_all_post",
    "parameters": [
     {
      "in": "path",
      "name": "adapter_name",
      "required": true,
      "schema": {
       "title": "Adapter Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Approve All Adapter Permissions",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/ai-models/adapters/{adapter_name}/permissions/grant": {
   "post": {
    "description": "Grant permission keys for an adapter (\u00a78 / \u00a711). Governance\nmutation \u2014 writes an audit log recording the actor, adapter, keys,\nand the grant_id KAI-C returns.\n\nRequires authenticated user.",
    "operationId": "grant_adapter_permissions_api_v1_ai_models_adapters__adapter_name__permissions_grant_post",
    "parameters": [
     {
      "in": "path",
      "name": "adapter_name",
      "required": true,
      "schema": {
       "title": "Adapter Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PermissionKeysRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Grant Adapter Permissions",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/ai-models/adapters/{adapter_name}/permissions/revoke": {
   "post": {
    "description": "Revoke permission keys for an adapter (\u00a78 / \u00a711). Revoking any\nkey flips the adapter back to pending and stops it serving. Writes\nan audit log.\n\nRequires authenticated user.",
    "operationId": "revoke_adapter_permissions_api_v1_ai_models_adapters__adapter_name__permissions_revoke_post",
    "parameters": [
     {
      "in": "path",
      "name": "adapter_name",
      "required": true,
      "schema": {
       "title": "Adapter Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PermissionKeysRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Revoke Adapter Permissions",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/ai-models/capabilities": {
   "get": {
    "description": "Fetch all available capabilities from KAI-C.\n\nKAI-C queries its configured adapters and returns combined capabilities.\nUsers never need to provide adapter URLs.\n\nRequires authenticated user.",
    "operationId": "get_capabilities_api_v1_ai_models_capabilities_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CapabilitiesResponse"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Capabilities",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/ai-models/health": {
   "get": {
    "description": "Check if KAI-C and its configured AI Adapters are healthy.\n\nUsers only need to know about KAI-C, not individual adapter URLs.\n\nRequires authenticated user.",
    "operationId": "check_kai_c_health_api_v1_ai_models_health_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/KaiCHealthResponse"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Check Kai C Health",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/ai-models/inference": {
   "post": {
    "description": "Run AI inference on a camera stream.\n\nThis endpoint:\n1. Captures a frame from the RTSP stream\n2. Sends it to KAI-C (which routes to correct adapter based on model_name)\n3. Returns the inference results\n\nUsers never provide adapter URLs - KAI-C handles routing internally.\n\nRequires authenticated user.",
    "operationId": "run_inference_api_v1_ai_models_inference_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/InferenceRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/InferenceResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Run Inference",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/ai-models/inference/recording": {
   "post": {
    "description": "Run AI inference on recorded video(s).\n\nSupports:\n- Single recording file (legacy: recording_path)\n- Recording session (session_id + segments)\n- Time-range selection (start_time, end_time)\n\nResults stream to database in real-time (similar to live inference).\n\nRequires authenticated user.",
    "operationId": "run_recording_inference_api_v1_ai_models_inference_recording_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RecordingInferenceRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Run Recording Inference",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/ai-models/schema": {
   "get": {
    "description": "Get schema documentation for tasks from KAI-C.\n\nKAI-C queries its configured adapters for schemas.\n\nRequires authenticated user.",
    "operationId": "get_task_schema_api_v1_ai_models_schema_get",
    "parameters": [
     {
      "in": "query",
      "name": "task",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Task"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Task Schema",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/ai-models/tasks": {
   "get": {
    "description": "The canonical task taxonomy: for each converged task, its canonical\nstring, label, categories/tags, which OpenNVR Agent skill it backs,\nand the non-canonical aliases that mean the same thing (contract \u00a74).\n\nCurated + open: an adapter may still advertise any free-text task it\nlikes (\u00a715.1); this registry adds canonical names, skill mapping, and\na lint. Product-owned editorial content, like the use-case map.",
    "operationId": "get_tasks_api_v1_ai_models_tasks_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "$ref": "#/components/schemas/TaskEntry"
         },
         "title": "Response Get Tasks Api V1 Ai Models Tasks Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Tasks",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/ai-models/tier0-gate": {
   "get": {
    "description": "The managed gate-mode override (guided promotion). ``null`` = follow env.",
    "operationId": "get_tier0_gate_api_v1_ai_models_tier0_gate_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Tier0 Gate",
    "tags": [
     "ai-models"
    ]
   },
   "put": {
    "description": "Set the gate mode from the UI (the promotion card's Enable/Revert).\n\nStored in the DB; the detect-pipeline picks it up on its next reconcile\ntick (~30 s) \u2014 no redeploy, no .env edit. Superuser-only: enforcement\nsuppresses expensive looks, which is a product decision.",
    "operationId": "set_tier0_gate_api_v1_ai_models_tier0_gate_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/Tier0GateUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set Tier0 Gate",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/ai-models/tier0-metrics": {
   "get": {
    "description": "Compute-gated (Tier-0) inference metrics for the app's panel.\n\nRead-only scrape of the detect-pipeline's Prometheus ``/metrics``\n(``detect_pipeline_metrics_url``), reduced to process CPU/RAM, the\nmotion-gate ratio, gate escalations vs suppressions, and the\nexpensive-model (Tier-1) call count/latency. Unreachable pipeline is a\nnormal state (gate off / not deployed) \u2192 ``{available: false}``; never 502.",
    "operationId": "get_tier0_metrics_api_v1_ai_models_tier0_metrics_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Tier0 Metrics",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/ai-models/use-cases": {
   "get": {
    "description": "The curated intent map: use case -> required capability -> suggested\napps and adapters. Product-owned editorial content (adapters never\ndeclare use cases themselves); powers the capability catalog's\nuse-case door.",
    "operationId": "get_use_cases_api_v1_ai_models_use_cases_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "$ref": "#/components/schemas/UseCaseEntry"
         },
         "title": "Response Get Use Cases Api V1 Ai Models Use Cases Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Use Cases",
    "tags": [
     "ai-models"
    ]
   }
  },
  "/api/v1/alerts-inbox": {
   "get": {
    "description": "Inbox listing, newest first. ``unacked=true`` is what the bell\npolls; the full list backs the Alerts & Incidents page.\n\nTWO counts come back, and they answer different questions. Reading\none as the other is the mistake this docstring exists to prevent:\n\n``unacked_count`` is the BELL BADGE \u2014 how many unacknowledged alerts\nexist in the caller's scope, ignoring every filter on this request\n(including ``unacked`` itself). It is why the bell can show \"12\"\nwhile the page below it shows three rows.\n\n``total`` is how many rows THIS request's filters match, for the\npager's \"1-25 of 312\". So ``?severity=critical`` can legitimately\nreturn ``unacked_count: 40`` beside ``total: 3``.",
    "operationId": "list_alerts_api_v1_alerts_inbox_get",
    "parameters": [
     {
      "description": "Only unacknowledged alerts",
      "in": "query",
      "name": "unacked",
      "required": false,
      "schema": {
       "default": false,
       "description": "Only unacknowledged alerts",
       "title": "Unacked",
       "type": "boolean"
      }
     },
     {
      "in": "query",
      "name": "severity",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Severity"
      }
     },
     {
      "in": "query",
      "name": "source_name",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Source Name"
      }
     },
     {
      "description": "The producer's kind of alert, e.g. scanner_flag",
      "in": "query",
      "name": "alert_type",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "The producer's kind of alert, e.g. scanner_flag",
       "title": "Alert Type"
      }
     },
     {
      "description": "Camera handle as the producer sent it (cam3)",
      "in": "query",
      "name": "camera_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Camera handle as the producer sent it (cam3)",
       "title": "Camera Id"
      }
     },
     {
      "description": "ISO-8601 lower bound on fired_at",
      "in": "query",
      "name": "from",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "ISO-8601 lower bound on fired_at",
       "title": "From"
      }
     },
     {
      "description": "ISO-8601 upper bound on fired_at",
      "in": "query",
      "name": "to",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "ISO-8601 upper bound on fired_at",
       "title": "To"
      }
     },
     {
      "description": "Substring of the title or description",
      "in": "query",
      "name": "q",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Substring of the title or description",
       "title": "Q"
      }
     },
     {
      "description": "Only rows with id > after_id \u2014 lets the bell poll for 'anything new since my last look' cheaply",
      "in": "query",
      "name": "after_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "description": "Only rows with id > after_id \u2014 lets the bell poll for 'anything new since my last look' cheaply",
       "title": "After Id"
      }
     },
     {
      "description": "Only rows with id <= before_id \u2014 pins a paged table to the set it first saw, so arrivals cannot shuffle it",
      "in": "query",
      "name": "before_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "description": "Only rows with id <= before_id \u2014 pins a paged table to the set it first saw, so arrivals cannot shuffle it",
       "title": "Before Id"
      }
     },
     {
      "in": "query",
      "name": "skip",
      "required": false,
      "schema": {
       "default": 0,
       "maximum": 100000,
       "minimum": 0,
       "title": "Skip",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "maximum": 200,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Alerts",
    "tags": [
     "alerts-inbox"
    ]
   }
  },
  "/api/v1/alerts-inbox/ack": {
   "post": {
    "description": "Silence alerts. Idempotent \u2014 an already-acked id is left with its\nORIGINAL acknowledgement (first silencer wins the audit trail).\nOnly alerts the caller can see are touched: \"ack all\" silences MY\ninbox, and an id on someone else's camera is simply not found.",
    "operationId": "acknowledge_api_v1_alerts_inbox_ack_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AckIn"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Acknowledge",
    "tags": [
     "alerts-inbox"
    ]
   }
  },
  "/api/v1/alerts-inbox/actions": {
   "get": {
    "description": "Call / SMS / hooter configuration, secret masked (set/unset).",
    "operationId": "get_alarm_actions_api_v1_alerts_inbox_actions_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Alarm Actions",
    "tags": [
     "alerts-inbox"
    ]
   },
   "put": {
    "operationId": "put_alarm_actions_api_v1_alerts_inbox_actions_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ActionConfigIn"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Put Alarm Actions",
    "tags": [
     "alerts-inbox"
    ]
   }
  },
  "/api/v1/alerts-inbox/actions/test": {
   "post": {
    "description": "Run every ENABLED action once with a synthetic alarm and return\neach action's outcome \u2014 validates Twilio credentials and the relay\nURL without waiting for a real alarm. Skips the severity gate on\npurpose (the point is exercising the actions), but a disabled\naction stays disabled.",
    "operationId": "test_alarm_actions_api_v1_alerts_inbox_actions_test_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Test Alarm Actions",
    "tags": [
     "alerts-inbox"
    ]
   }
  },
  "/api/v1/alerts-inbox/ring-config": {
   "get": {
    "description": "Per-severity ring behaviour for the browser bell:\nnone | ping | continuous. Stored once, shared by every operator \u2014\nan alarm policy is a site decision, not a per-browser one.",
    "operationId": "get_ring_config_api_v1_alerts_inbox_ring_config_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Ring Config",
    "tags": [
     "alerts-inbox"
    ]
   },
   "put": {
    "description": "Replace the ring policy. Unknown severities/modes are rejected\nloudly rather than dropped \u2014 a typo'd 'continuos' that silently\nbecame the default would be discovered at 3am.",
    "operationId": "put_ring_config_api_v1_alerts_inbox_ring_config_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RingConfigIn"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Put Ring Config",
    "tags": [
     "alerts-inbox"
    ]
   }
  },
  "/api/v1/alerts-inbox/test": {
   "post": {
    "description": "Fire a synthetic alarm through the REAL ingestion path.\n\n'Is the alarm system working?' deserves a one-click answer that\nexercises the same code a real alert takes \u2014 apply_alert, the same\ntable, the same poll, the same ring \u2014 not a UI-only sound test that\nwould pass while the consumer is broken. The alert is clearly\nlabelled as a test and acknowledges like any other.",
    "operationId": "fire_test_alarm_api_v1_alerts_inbox_test_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TestAlarmIn"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Fire Test Alarm",
    "tags": [
     "alerts-inbox"
    ]
   }
  },
  "/api/v1/alerts-inbox/{alert_id}/images/{name}": {
   "get": {
    "description": "One evidence photo off an alert \u2014 the face, the body, the scene.\n\n``name`` is the key the producer used, not a path: the path comes\nfrom the row, so a caller cannot ask for a file the alert does not\nreference.",
    "operationId": "get_alert_image_api_v1_alerts_inbox__alert_id__images__name__get",
    "parameters": [
     {
      "in": "path",
      "name": "alert_id",
      "required": true,
      "schema": {
       "title": "Alert Id",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Alert Image",
    "tags": [
     "alerts-inbox"
    ]
   }
  },
  "/api/v1/apps": {
   "get": {
    "description": "List all installed apps \u2014 the catalog's data source.\n\nEach card checks ``manifest.requires_tasks`` against\n``GET /api/v1/adapters`` client-side to grey out apps whose model\nprerequisites aren't met.\n\nRequires an authenticated user OR the deployment's internal API key\n(``X-Internal-Api-Key``) \u2014 a service (the OpenNVR Agent) reads the\ncatalog to relay installed apps as conversational skills. Read only;\nsee :func:`get_read_principal`.",
    "operationId": "list_apps_api_v1_apps_get",
    "parameters": [
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Apps",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/bus": {
   "get": {
    "description": "The apps bus and its leaf link to the platform bus, as core last\nsaw it (``services/apps_bus_watch.py``). ``linked: false`` for more\nthan the grace period is the \"apps are up but alerts stopped\"\ncondition; the inbox alert says the same thing.",
    "operationId": "get_apps_bus_api_v1_apps_bus_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Apps Bus",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/egress/check": {
   "post": {
    "description": "The egress proxy's question \u2014 site key only. Answers\n``{allowed, app_id, reason}``; a denial is logged, counted and, once\nper app and destination per hour, raised in the inbox.",
    "operationId": "egress_check_api_v1_apps_egress_check_post",
    "parameters": [
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/EgressCheckIn"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Egress Check",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/index": {
   "get": {
    "description": "The App Store \"discover\" listing \u2014 the browse-and-install catalog.\n\nLoads the curated ``apps_index.yml`` (product-owned editorial, one\nentry per shipped example) and cross-references the ``installed_apps``\nregistry so each entry carries ``installed`` (an installed_apps row\nwith that id exists) and ``enabled`` (that row's flag, or ``null``\nwhen not installed). The UI shows \"installed\" vs \"available to\ninstall\" from this alone.\n\nNever 404s \u2014 an entry that isn't installed simply has\n``installed=false, enabled=null``. The index yaml ships with the\nserver, so a load/validation failure is a 500 (a broken deploy),\nnot an empty list.\n\nRequires authenticated user.",
    "operationId": "get_apps_index_api_v1_apps_index_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Apps Index",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/index/{app_id}/install": {
   "post": {
    "description": "Opt-in one-click install \u2014 write a DESIRED-STATE record only.\n\nGated by BOTH ``APPS_INSTALL_ENABLED`` (403 when off \u2014 the sovereign\ndefault) AND the ``apps.install`` RBAC permission (via the dependency\nabove). The app id must be in the curated ``apps_index.yml`` (404\notherwise) \u2014 no arbitrary images. image/digest are copied from the\nindex, never from the caller.\n\nThis endpoint does NOT run Docker: it upserts one\n``app_install_intents`` row with ``desired=\"installed\"``,\n``status=\"pending\"`` and audits it. The ``scripts/app-installer``\nreconciler applies it.",
    "operationId": "install_app_api_v1_apps_index__app_id__install_post",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Install App",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/index/{app_id}/install-status": {
   "get": {
    "description": "Report the desired-state + reconcile status for one curated app.\n\nReadable by any authenticated user (it's status, not a mutation).\nThe id must be in the curated index (404 otherwise). When no intent\nhas ever been written, returns ``desired=null, status=\"none\"`` so the\nUI can distinguish \"never requested\" from \"pending\".",
    "operationId": "get_install_status_api_v1_apps_index__app_id__install_status_get",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Install Status",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/index/{app_id}/uninstall": {
   "post": {
    "description": "Opt-in one-click uninstall \u2014 flip the desired state to ``absent``.\n\nSame gates as install (opt-in flag + apps.install + index-only).\nWrites ``desired=\"absent\"``, ``status=\"pending\"`` on the intent row\nand audits it; the reconciler brings the app's compose stack down.",
    "operationId": "uninstall_app_api_v1_apps_index__app_id__uninstall_post",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Uninstall App",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/register": {
   "post": {
    "description": "Register (or re-register) an app \u2014 the SDK calls this on boot.\n\nUpserts by manifest id: url / manifest / name / version / category\nrefresh on every boot, while the operator-owned ``enabled`` flag\nand ``config_json`` survive restarts.\n\nThe app URL must pass :func:`validate_app_url` \u2014 /status later\nserver-side fetches it, so off-box URLs are refused here (SSRF).\n\nRequires an authenticated user OR the deployment's internal API\nkey (``X-Internal-Api-Key``) \u2014 registration is service-to-service;\nsee :func:`get_register_principal`.",
    "operationId": "register_app_api_v1_apps_register_post",
    "parameters": [
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AppRegisterRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Register App",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/{app_id}/actions/{action_name}": {
   "post": {
    "description": "Invoke one manifest-declared action on the app's contract surface.\n\nGOVERNANCE: **user-JWT only** \u2014 deliberately NOT ``get_read_principal``.\nActions are operator verbs (search footage, enroll a face); the\nOpenNVR Agent's service key must never satisfy THIS route. The full\nboundary is layered (see ``Action`` in the SDK's manifest module):\nthis JWT gate on the proxy, the deployment-key check on the app's\nown POST surface, and the agent shipping no HTTP-POST tool at all.\nDo not widen this dependency.\n\nGates, in order: the app must be registered AND enabled; the action\nmust be DECLARED in the stored manifest (404 otherwise \u2014 the\nmanifest is the single source of truth for operator verbs); params\nare validated against the declared ``Action.params`` exactly like\n``PUT /config`` validates against ``params``; the stored URL is\nre-checked against :func:`validate_app_url` before any fetch. Every\ninvocation writes an audit row. The app's response is returned\nverbatim (its 4xx/5xx map to 502 with the app's error detail).",
    "operationId": "invoke_app_action_api_v1_apps__app_id__actions__action_name__post",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     },
     {
      "in": "path",
      "name": "action_name",
      "required": true,
      "schema": {
       "title": "Action Name",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Params",
        "type": "object"
       }
      }
     }
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Invoke App Action",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/{app_id}/config": {
   "get": {
    "description": "Read one app's effective config from the registry.\n\nThis is the poll target for the SDK's LIVE CONFIG DELIVERY: the\nregistry is the single source of truth (spec \u00a705) and the running\napp polls this endpoint (with the deployment's internal key it\nalready holds for registration) to apply operator edits made in the\ncatalog's config form WITHOUT a container restart.\n\nRead-only, hence ``get_read_principal`` (user JWT **or**\n``X-Internal-Api-Key``): the app itself is the intended service\ncaller. Writes stay user-JWT-only (``PUT`` below).",
    "operationId": "get_app_config_api_v1_apps__app_id__config_get",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get App Config",
    "tags": [
     "apps"
    ]
   },
   "put": {
    "description": "Replace an app's config, validated against ``manifest.params``.\n\nBecause the manifest is typed and declarative, this endpoint needs\nzero app-specific code \u2014 see :func:`validate_app_config`.\n\nManifest defaults are materialized into the stored config: any\nparam omitted from the payload whose manifest ``default`` is not\nNone is filled in before persisting (provided values are never\noverwritten), so ``config_json`` is the effective config and the\nregistry stays the single source of truth (spec \u00a705).\n\nAuthorization: a superuser may change anything. Any other user may\nchange ONLY the ``per_camera`` entries (zones, tripwires, per-camera\nlimits) of cameras they can manage; a site-wide key or another\ncamera's entry arriving CHANGED is a 403, and entries for cameras\nthey cannot see (trimmed from their read) are preserved. The global\nsettings of an app (its watchlists, thresholds, alarm policy) are a\nsite decision, not a per-operator one.",
    "operationId": "update_app_config_api_v1_apps__app_id__config_put",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Config",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update App Config",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/{app_id}/disable": {
   "post": {
    "description": "Disable an app. 404 if the app was never registered.\n\nSuperuser only \u2014 turning a site-wide app off silences it for\nevery operator's cameras, not just the caller's.",
    "operationId": "disable_app_api_v1_apps__app_id__disable_post",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Disable App",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/{app_id}/egress": {
   "get": {
    "description": "Declared, allowed and enforced hosts, plus recent denials. Any\nauthenticated user, or the site key (the catalog reads it).",
    "operationId": "get_app_egress_api_v1_apps__app_id__egress_get",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get App Egress",
    "tags": [
     "apps"
    ]
   },
   "put": {
    "description": "Replace the operator's allow list for this install (superuser).\nHost rules only: ``host``, ``*.domain``, an IPv4 address or CIDR,\noptionally ``:port``.",
    "operationId": "put_app_egress_api_v1_apps__app_id__egress_put",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/EgressAllowIn"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Put App Egress",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/{app_id}/enable": {
   "post": {
    "description": "Enable an app. 404 if the app was never registered.\n\nSuperuser only \u2014 turning a site-wide app on is a site decision.\nA licensed app (manifest ``entitlement: license_key``) also needs\na key the app has accepted \u2014 402 otherwise, with the reason.",
    "operationId": "enable_app_api_v1_apps__app_id__enable_post",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Enable App",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/{app_id}/key": {
   "delete": {
    "description": "Revoke the app's key: it can no longer read its config, its\nroster, or re-register with that key. Superuser only.",
    "operationId": "revoke_app_key_api_v1_apps__app_id__key_delete",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Revoke App Key",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/{app_id}/key/rotate": {
   "post": {
    "description": "Mint a NEW app key and return it once; the old one stops working\nimmediately. Superuser only. Hand the value to the app's operator\n(``OPENNVR_APP_KEY``), or restart the app with the site key and it\nasks for one itself (``wants_key``).",
    "operationId": "rotate_app_key_api_v1_apps__app_id__key_rotate_post",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Rotate App Key",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/{app_id}/license": {
   "delete": {
    "description": "Forget the key. A licensed app that is enabled stays enabled\nuntil it is next toggled \u2014 revoking a key is not an outage.",
    "operationId": "delete_app_license_api_v1_apps__app_id__license_delete",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete App License",
    "tags": [
     "apps"
    ]
   },
   "put": {
    "description": "Store a licence key (encrypted, never returned) and ask the app\nto verify it. Superuser only. Returns the verdict; enabling the app\nis refused until it is ``valid``.",
    "operationId": "put_app_license_api_v1_apps__app_id__license_put",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/LicenseIn"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Put App License",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/{app_id}/license/verify": {
   "post": {
    "description": "Re-ask the app about the stored key (after a renewal, or when the\napp was down when the key was entered).",
    "operationId": "verify_app_license_api_v1_apps__app_id__license_verify_post",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Verify App License",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/{app_id}/overlay": {
   "put": {
    "description": "Allow (or stop allowing) this app's ``overlay.boxes.v1`` events to\nbe drawn over the live video. Superuser: an app painting on every\noperator's screen is a site decision. The app itself is untouched \u2014\nit keeps publishing; the bridge just stops forwarding.",
    "operationId": "set_app_overlay_api_v1_apps__app_id__overlay_put",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/OverlayToggle"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set App Overlay",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/{app_id}/status": {
   "get": {
    "description": "Proxy the app's live ``/health`` and ``/state`` endpoints.\n\nDegrades gracefully: an unreachable app yields\n``{\"health\": {\"status\": \"unreachable\"}, \"state\": None}`` rather\nthan a 5xx, and the stored row status flips to ``unreachable`` so\nthe catalog dot goes red without polling the app itself.\n\nThe stored URL is re-checked against :func:`validate_app_url`\nbefore any fetch (defense in depth for rows registered before the\nguard existed): a blocked URL short-circuits to\n``{\"health\": {\"status\": \"blocked_url\"}, \"state\": None}``.\n\nRequires an authenticated user OR the deployment's internal API key\n(``X-Internal-Api-Key``) \u2014 a service reads live app state to relay\nit; see :func:`get_read_principal`. Read only.",
    "operationId": "get_app_status_api_v1_apps__app_id__status_get",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get App Status",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/apps/{app_id}/ui": {
   "get": {
    "description": "Proxy the app's ``GET /ui`` dashboard (RFC-0002 Phase 4).\n\nThe app-surface routing convention: an app that sets ``has_ui`` in\nits manifest serves ONE self-contained HTML document at ``/ui`` on\nits contract port, and this route is how the operator UI reaches it\n\u2014 apps never get their own public ports. Deliberately minimal:\n\n* **user-JWT only** (like actions): dashboards are operator surface;\n  the service key must never satisfy this route.\n* ``/ui`` exactly \u2014 no subpaths, no assets, no methods but GET. A\n  dashboard that needs more than one self-contained document should\n  argue for widening the convention in an RFC, not around it.\n* the response is size-capped and always served as text/html; the\n  catalog renders it inside a SANDBOXED iframe (no scripts), so\n  pages should be static HTML/CSS.",
    "operationId": "get_app_ui_api_v1_apps__app_id__ui_get",
    "parameters": [
     {
      "in": "path",
      "name": "app_id",
      "required": true,
      "schema": {
       "title": "App Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get App Ui",
    "tags": [
     "apps"
    ]
   }
  },
  "/api/v1/audit-logs/": {
   "get": {
    "operationId": "list_audit_logs_api_v1_audit_logs__get",
    "parameters": [
     {
      "in": "query",
      "name": "skip",
      "required": false,
      "schema": {
       "default": 0,
       "minimum": 0,
       "title": "Skip",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "maximum": 500,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "action",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Action"
      }
     },
     {
      "in": "query",
      "name": "entity_type",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Entity Type"
      }
     },
     {
      "in": "query",
      "name": "user_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "User Id"
      }
     },
     {
      "in": "query",
      "name": "start",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "format": "date-time",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Start"
      }
     },
     {
      "in": "query",
      "name": "end",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "format": "date-time",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "End"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AuditLogList"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Audit Logs",
    "tags": [
     "audit-logs"
    ]
   }
  },
  "/api/v1/auth/check-setup": {
   "post": {
    "description": "Check if first-time setup is required for admin user.",
    "operationId": "check_first_time_setup_api_v1_auth_check_setup_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/FirstTimeSetupCheckResponse"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Check First Time Setup",
    "tags": [
     "authentication"
    ]
   }
  },
  "/api/v1/auth/first-time-setup": {
   "post": {
    "description": "Complete first-time setup: set password and enable MFA.",
    "operationId": "first_time_setup_api_v1_auth_first_time_setup_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/FirstTimeSetupRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/FirstTimeSetupResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "First Time Setup",
    "tags": [
     "authentication"
    ]
   }
  },
  "/api/v1/auth/login": {
   "post": {
    "description": "Login endpoint to get access token (supports MFA if enabled).",
    "operationId": "login_for_access_token_api_v1_auth_login_post",
    "requestBody": {
     "content": {
      "application/x-www-form-urlencoded": {
       "schema": {
        "$ref": "#/components/schemas/Body_login_for_access_token_api_v1_auth_login_post"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Token"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Login For Access Token",
    "tags": [
     "authentication"
    ]
   }
  },
  "/api/v1/auth/login-json": {
   "post": {
    "description": "Alternative login endpoint using JSON body with optional TOTP code.",
    "operationId": "login_with_json_api_v1_auth_login_json_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/UserLogin"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Token"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Login With Json",
    "tags": [
     "authentication"
    ]
   }
  },
  "/api/v1/auth/logout": {
   "post": {
    "description": "Stateless logout endpoint. Frontend can call this to record a logout event.",
    "operationId": "logout_api_v1_auth_logout_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Logout",
    "tags": [
     "authentication"
    ]
   }
  },
  "/api/v1/auth/me": {
   "get": {
    "description": "Get current user information.",
    "operationId": "read_users_me_api_v1_auth_me_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/UserResponse"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Read Users Me",
    "tags": [
     "authentication"
    ]
   }
  },
  "/api/v1/auth/mfa/disable": {
   "post": {
    "description": "Disable MFA for current user.",
    "operationId": "mfa_disable_api_v1_auth_mfa_disable_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Mfa Disable",
    "tags": [
     "authentication"
    ]
   }
  },
  "/api/v1/auth/mfa/setup": {
   "post": {
    "description": "Generate and return provisioning URI + secret for TOTP; store secret disabled until verify.",
    "operationId": "mfa_setup_api_v1_auth_mfa_setup_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/MfaSetupResponse"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Mfa Setup",
    "tags": [
     "authentication"
    ]
   }
  },
  "/api/v1/auth/mfa/verify": {
   "post": {
    "description": "Verify user-provided TOTP code to enable MFA.",
    "operationId": "mfa_verify_api_v1_auth_mfa_verify_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MfaVerifyRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Mfa Verify",
    "tags": [
     "authentication"
    ]
   }
  },
  "/api/v1/auth/refresh": {
   "post": {
    "description": "Exchange a valid refresh token for a new access token and refresh token pair.",
    "operationId": "refresh_access_token_api_v1_auth_refresh_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/Body_refresh_access_token_api_v1_auth_refresh_post"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Token"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Refresh Access Token",
    "tags": [
     "authentication"
    ]
   }
  },
  "/api/v1/auth/register": {
   "post": {
    "description": "Self-service registration (viewer role). Off unless the operator\nopted in with ``PUBLIC_REGISTRATION_ENABLED`` \u2014 accounts on an NVR\nare otherwise the administrator's to create (``POST /users``).",
    "operationId": "register_user_api_v1_auth_register_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/UserRegister"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/UserResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Register User",
    "tags": [
     "authentication"
    ]
   }
  },
  "/api/v1/camera-config/": {
   "post": {
    "operationId": "create_config_api_v1_camera_config__post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CameraConfigCreate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CameraConfigResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create Config",
    "tags": [
     "camera-config"
    ]
   }
  },
  "/api/v1/camera-config/{camera_id}": {
   "get": {
    "operationId": "get_config_api_v1_camera_config__camera_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CameraConfigResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Config",
    "tags": [
     "camera-config"
    ]
   },
   "put": {
    "operationId": "update_config_api_v1_camera_config__camera_id__put",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CameraConfigUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CameraConfigResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Config",
    "tags": [
     "camera-config"
    ]
   }
  },
  "/api/v1/camera-config/{camera_id}/provision": {
   "post": {
    "operationId": "provision_api_v1_camera_config__camera_id__provision_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProvisionResult"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Provision",
    "tags": [
     "camera-config"
    ]
   }
  },
  "/api/v1/camera-config/{camera_id}/status": {
   "get": {
    "operationId": "path_status_api_v1_camera_config__camera_id__status_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Path Status",
    "tags": [
     "camera-config"
    ]
   }
  },
  "/api/v1/camera-config/{camera_id}/unprovision": {
   "post": {
    "operationId": "unprovision_api_v1_camera_config__camera_id__unprovision_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/ProvisionResult"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Unprovision",
    "tags": [
     "camera-config"
    ]
   }
  },
  "/api/v1/camera/{ip}/profiles": {
   "get": {
    "description": "Get media profiles from camera. Set use_digest=true for Hikvision devices.",
    "operationId": "camera_profiles_api_v1_camera__ip__profiles_get",
    "parameters": [
     {
      "in": "path",
      "name": "ip",
      "required": true,
      "schema": {
       "title": "Ip",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "port",
      "required": false,
      "schema": {
       "default": 80,
       "maximum": 65535,
       "minimum": 1,
       "title": "Port",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "username",
      "required": true,
      "schema": {
       "title": "Username",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "password",
      "required": true,
      "schema": {
       "title": "Password",
       "type": "string"
      }
     },
     {
      "description": "Use HTTP Digest auth (better Hikvision compatibility)",
      "in": "query",
      "name": "use_digest",
      "required": false,
      "schema": {
       "default": true,
       "description": "Use HTTP Digest auth (better Hikvision compatibility)",
       "title": "Use Digest",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Camera Profiles",
    "tags": [
     "onvif"
    ]
   }
  },
  "/api/v1/camera/{ip}/ptz/move": {
   "post": {
    "operationId": "camera_ptz_move_api_v1_camera__ip__ptz_move_post",
    "parameters": [
     {
      "in": "path",
      "name": "ip",
      "required": true,
      "schema": {
       "title": "Ip",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "x",
      "required": false,
      "schema": {
       "default": 0.0,
       "maximum": 1.0,
       "minimum": -1.0,
       "title": "X",
       "type": "number"
      }
     },
     {
      "in": "query",
      "name": "y",
      "required": false,
      "schema": {
       "default": 0.0,
       "maximum": 1.0,
       "minimum": -1.0,
       "title": "Y",
       "type": "number"
      }
     },
     {
      "in": "query",
      "name": "z",
      "required": false,
      "schema": {
       "default": 0.0,
       "maximum": 1.0,
       "minimum": -1.0,
       "title": "Z",
       "type": "number"
      }
     },
     {
      "in": "query",
      "name": "profileToken",
      "required": true,
      "schema": {
       "title": "Profiletoken",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "port",
      "required": false,
      "schema": {
       "default": 80,
       "maximum": 65535,
       "minimum": 1,
       "title": "Port",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "username",
      "required": true,
      "schema": {
       "title": "Username",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "password",
      "required": true,
      "schema": {
       "title": "Password",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Camera Ptz Move",
    "tags": [
     "onvif"
    ]
   }
  },
  "/api/v1/camera/{ip}/ptz/preset": {
   "post": {
    "operationId": "camera_ptz_preset_api_v1_camera__ip__ptz_preset_post",
    "parameters": [
     {
      "in": "path",
      "name": "ip",
      "required": true,
      "schema": {
       "title": "Ip",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "action",
      "required": true,
      "schema": {
       "title": "Action",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "profileToken",
      "required": true,
      "schema": {
       "title": "Profiletoken",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "name",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Name"
      }
     },
     {
      "in": "query",
      "name": "presetToken",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Presettoken"
      }
     },
     {
      "in": "query",
      "name": "port",
      "required": false,
      "schema": {
       "default": 80,
       "maximum": 65535,
       "minimum": 1,
       "title": "Port",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "username",
      "required": true,
      "schema": {
       "title": "Username",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "password",
      "required": true,
      "schema": {
       "title": "Password",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Camera Ptz Preset",
    "tags": [
     "onvif"
    ]
   }
  },
  "/api/v1/camera/{ip}/ptz/stop": {
   "post": {
    "operationId": "camera_ptz_stop_api_v1_camera__ip__ptz_stop_post",
    "parameters": [
     {
      "in": "path",
      "name": "ip",
      "required": true,
      "schema": {
       "title": "Ip",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "profileToken",
      "required": true,
      "schema": {
       "title": "Profiletoken",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "port",
      "required": false,
      "schema": {
       "default": 80,
       "maximum": 65535,
       "minimum": 1,
       "title": "Port",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "username",
      "required": true,
      "schema": {
       "title": "Username",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "password",
      "required": true,
      "schema": {
       "title": "Password",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Camera Ptz Stop",
    "tags": [
     "onvif"
    ]
   }
  },
  "/api/v1/camera/{ip}/stream-uri": {
   "get": {
    "description": "Get stream URI for a profile. Set use_digest=true for Hikvision devices.",
    "operationId": "camera_stream_uri_api_v1_camera__ip__stream_uri_get",
    "parameters": [
     {
      "in": "path",
      "name": "ip",
      "required": true,
      "schema": {
       "title": "Ip",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "profileToken",
      "required": true,
      "schema": {
       "title": "Profiletoken",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "port",
      "required": false,
      "schema": {
       "default": 80,
       "maximum": 65535,
       "minimum": 1,
       "title": "Port",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "username",
      "required": true,
      "schema": {
       "title": "Username",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "password",
      "required": true,
      "schema": {
       "title": "Password",
       "type": "string"
      }
     },
     {
      "description": "Use HTTP Digest auth (better Hikvision compatibility)",
      "in": "query",
      "name": "use_digest",
      "required": false,
      "schema": {
       "default": true,
       "description": "Use HTTP Digest auth (better Hikvision compatibility)",
       "title": "Use Digest",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Camera Stream Uri",
    "tags": [
     "onvif"
    ]
   }
  },
  "/api/v1/camera/{ip}/time": {
   "get": {
    "description": "Read the camera clock via GetSystemDateAndTime (no credentials needed).",
    "operationId": "camera_get_time_api_v1_camera__ip__time_get",
    "parameters": [
     {
      "in": "path",
      "name": "ip",
      "required": true,
      "schema": {
       "title": "Ip",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "port",
      "required": false,
      "schema": {
       "default": 80,
       "maximum": 65535,
       "minimum": 1,
       "title": "Port",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Camera Get Time",
    "tags": [
     "onvif"
    ]
   }
  },
  "/api/v1/camera/{ip}/time/sync": {
   "post": {
    "description": "Push the NVR's current UTC time to the camera (superuser only).",
    "operationId": "camera_sync_time_api_v1_camera__ip__time_sync_post",
    "parameters": [
     {
      "in": "path",
      "name": "ip",
      "required": true,
      "schema": {
       "title": "Ip",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "port",
      "required": false,
      "schema": {
       "default": 80,
       "maximum": 65535,
       "minimum": 1,
       "title": "Port",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "username",
      "required": true,
      "schema": {
       "title": "Username",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "password",
      "required": true,
      "schema": {
       "title": "Password",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Camera Sync Time",
    "tags": [
     "onvif"
    ]
   }
  },
  "/api/v1/cameras/": {
   "get": {
    "description": "Get list of cameras (user's own cameras + permitted cameras; superusers see all).",
    "operationId": "get_cameras_api_v1_cameras__get",
    "parameters": [
     {
      "in": "query",
      "name": "skip",
      "required": false,
      "schema": {
       "default": 0,
       "title": "Skip",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 100,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "active_only",
      "required": false,
      "schema": {
       "default": true,
       "title": "Active Only",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CameraList"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Cameras",
    "tags": [
     "cameras"
    ]
   },
   "post": {
    "description": "Create a new camera. Requires the ``cameras.manage`` permission\n(superusers hold it implicitly).\n\nWhen no RTSP URL is supplied but credentials are, the server derives it\nfrom the IP + credentials (ONVIF direct-connect, then vendor RTSP\ntemplates) and back-fills the camera's identity \u2014 so operators normally\nonly need IP + username + password.",
    "operationId": "create_camera_api_v1_cameras__post",
    "parameters": [
     {
      "description": "Add the camera even when its IP or RTSP URL matches an existing one.",
      "in": "query",
      "name": "force",
      "required": false,
      "schema": {
       "default": false,
       "description": "Add the camera even when its IP or RTSP URL matches an existing one.",
       "title": "Force",
       "type": "boolean"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CameraCreate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CameraResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create Camera",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/assignable-skills": {
   "get": {
    "description": "Suggestions + live availability for the Assignments editor.",
    "operationId": "assignable_skills_api_v1_cameras_assignable_skills_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Assignable Skills",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/by-ip/{ip_address}": {
   "get": {
    "description": "Get all cameras for a specific IP address (user's own cameras + permitted cameras; superusers see all).",
    "operationId": "get_cameras_by_ip_api_v1_cameras_by_ip__ip_address__get",
    "parameters": [
     {
      "in": "path",
      "name": "ip_address",
      "required": true,
      "schema": {
       "title": "Ip Address",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "active_only",
      "required": false,
      "schema": {
       "default": true,
       "title": "Active Only",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "$ref": "#/components/schemas/CameraResponse"
         },
         "title": "Response Get Cameras By Ip Api V1 Cameras By Ip  Ip Address  Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Cameras By Ip",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/deleted": {
   "get": {
    "description": "List binned (soft-deleted) cameras \u2014 the Deleted Cameras page.\n\nSuperusers see every binned camera, other users only their own. These\ncameras can never be edited or reactivated; their recordings remain\nplayable (via the returned ``path``) until retention removes them, and a\nsuperuser can purge them permanently via the hard-delete endpoint.",
    "operationId": "get_deleted_cameras_api_v1_cameras_deleted_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/DeletedCameraList"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Deleted Cameras",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}": {
   "delete": {
    "description": "Delete a camera (irreversible soft delete).\n\nTears down the MediaMTX path immediately (stops live view and recording),\nstamps ``deleted_at`` and moves the camera to the bin: it disappears from\nevery normal list, can never be edited or reactivated, and its recordings\nstay viewable only through the bin until retention ages them out. The\nalready-deleted case 404s via get_camera_or_403.",
    "operationId": "delete_camera_api_v1_cameras__camera_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete Camera",
    "tags": [
     "cameras"
    ]
   },
   "get": {
    "description": "Get camera by ID (owner, superuser, or permitted users).",
    "operationId": "get_camera_api_v1_cameras__camera_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CameraResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Camera",
    "tags": [
     "cameras"
    ]
   },
   "put": {
    "description": "Update camera information (owner or superuser).\n\nToggling ``is_active`` is the reversible pause: deactivating immediately\ntears down the camera's MediaMTX path (stops live view and recording),\nreactivating re-provisions it. The flag is the source of truth \u2014 a\nMediaMTX hiccup never blocks the state change.",
    "operationId": "update_camera_api_v1_cameras__camera_id__put",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CameraUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CameraResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Camera",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/camera-users": {
   "get": {
    "description": "List on-camera user accounts (the one OpenNVR uses is flagged).",
    "operationId": "list_camera_users_api_v1_cameras__camera_id__camera_users_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Camera Users",
    "tags": [
     "camera-settings"
    ]
   },
   "post": {
    "description": "Create a new on-camera account. Write-gated (``camera_device.write``):\nan on-camera Administrator account outlives OpenNVR itself.",
    "operationId": "create_camera_user_api_v1_cameras__camera_id__camera_users_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CameraUserCreate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create Camera User",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/camera-users/{username}": {
   "delete": {
    "description": "Delete an on-camera account. Write-gated (``camera_device.write``).\nRefuses the account OpenNVR itself uses.",
    "operationId": "delete_camera_user_api_v1_cameras__camera_id__camera_users__username__delete",
    "parameters": [
     {
      "in": "path",
      "name": "username",
      "required": true,
      "schema": {
       "title": "Username",
       "type": "string"
      }
     },
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete Camera User",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/capabilities": {
   "get": {
    "description": "Cached capability snapshot (probes once if never probed).",
    "operationId": "get_capabilities_api_v1_cameras__camera_id__capabilities_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Capabilities",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/capabilities/refresh": {
   "post": {
    "description": "Force a fresh capability probe (also refreshes device metadata).",
    "operationId": "refresh_capabilities_api_v1_cameras__camera_id__capabilities_refresh_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Refresh Capabilities",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/config-backup": {
   "post": {
    "description": "Download the camera's full configuration blob (vendor backup format).\nWrite-gated (``camera_device.write``): the blob can contain device secrets.",
    "operationId": "export_camera_config_api_v1_cameras__camera_id__config_backup_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ConfigBackupRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Export Camera Config",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/encoder": {
   "get": {
    "description": "Read the video-encoder configurations (main/sub) + their option ranges.",
    "operationId": "get_encoder_api_v1_cameras__camera_id__encoder_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Encoder",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/encoder/{config_token}": {
   "put": {
    "description": "Apply encoder changes to one configuration, then reconcile the MediaMTX\nstream (brief reconnect). The camera-side change stands even if the\nreconcile step reports it couldn't refresh the stream.",
    "operationId": "set_encoder_api_v1_cameras__camera_id__encoder__config_token__put",
    "parameters": [
     {
      "in": "path",
      "name": "config_token",
      "required": true,
      "schema": {
       "title": "Config Token",
       "type": "string"
      }
     },
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/EncoderUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set Encoder",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/events": {
   "get": {
    "description": "Recent camera-native alarm history (most recent first).",
    "operationId": "list_events_api_v1_cameras__camera_id__events_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Events",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/events/status": {
   "get": {
    "operationId": "events_status_api_v1_cameras__camera_id__events_status_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Events Status",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/events/subscribe": {
   "post": {
    "description": "Start streaming this camera's native alarms into OpenNVR (motion/tamper).\nEphemeral: subscriptions do not survive a server restart.",
    "operationId": "subscribe_events_api_v1_cameras__camera_id__events_subscribe_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Subscribe Events",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/events/unsubscribe": {
   "post": {
    "description": "Stop streaming this camera's alarms.",
    "operationId": "unsubscribe_events_api_v1_cameras__camera_id__events_unsubscribe_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Unsubscribe Events",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/hard-delete": {
   "post": {
    "description": "Permanently delete a binned camera: its DB rows and its recordings.\n\nSuperuser only, and deliberately hard to trigger by accident:\n- the camera must already be in the bin (soft-deleted) \u2014 409 otherwise;\n- the caller's current TOTP code must be in the X-MFA-Code header;\n- the body must carry the exact phrase\n  ``hard delete <camera name> and it's recording``.\n\nFiles are purged before rows so a failed purge stays retryable. A\nrecordings dir whose identity marker belongs to a *different* camera uuid\nis skipped, never deleted (it is that camera's archive).",
    "operationId": "hard_delete_camera_api_v1_cameras__camera_id__hard_delete_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "header",
      "name": "X-MFA-Code",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Mfa-Code"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CameraHardDeleteRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Hard Delete Camera",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/imaging": {
   "get": {
    "description": "Read image settings (brightness/contrast/\u2026, day-night, WDR) + ranges.",
    "operationId": "get_imaging_api_v1_cameras__camera_id__imaging_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Imaging",
    "tags": [
     "camera-settings"
    ]
   },
   "put": {
    "description": "Apply image settings (only provided fields; values clamped to ranges).",
    "operationId": "set_imaging_api_v1_cameras__camera_id__imaging_put",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ImagingUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set Imaging",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/info": {
   "get": {
    "description": "Live device identity read (manufacturer/model/firmware/serial).",
    "operationId": "get_info_api_v1_cameras__camera_id__info_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Info",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/mediamtx-status": {
   "get": {
    "description": "Get MediaMTX status for a camera including recording configuration.",
    "operationId": "get_camera_mediamtx_status_api_v1_cameras__camera_id__mediamtx_status_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Camera Mediamtx Status",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/motion": {
   "get": {
    "description": "Read motion-detection state (enabled, sensitivity).",
    "operationId": "get_motion_api_v1_cameras__camera_id__motion_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Motion",
    "tags": [
     "camera-settings"
    ]
   },
   "put": {
    "description": "Enable/disable motion detection and set its sensitivity.",
    "operationId": "set_motion_api_v1_cameras__camera_id__motion_put",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MotionUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set Motion",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/network": {
   "get": {
    "description": "READ-ONLY network configuration. There is no corresponding PUT.",
    "operationId": "get_network_api_v1_cameras__camera_id__network_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Network",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/osd": {
   "get": {
    "description": "Read on-screen overlays (date/time, channel name, custom text).",
    "operationId": "get_osd_api_v1_cameras__camera_id__osd_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Osd",
    "tags": [
     "camera-settings"
    ]
   },
   "put": {
    "description": "Toggle the date/time + channel-name overlays and set a custom text line.",
    "operationId": "set_osd_api_v1_cameras__camera_id__osd_put",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/OsdUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set Osd",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/permissions": {
   "get": {
    "description": "Every grant on a camera \u2014 who may view it, who may manage it \u2014\nwith the owner listed first. Owner or superuser (the same gate as\nassigning); the assignment API was write-only before this, so an\nadmin could grant but never audit.",
    "operationId": "list_camera_permissions_api_v1_cameras__camera_id__permissions_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "$ref": "#/components/schemas/CameraPermissionEntry"
         },
         "title": "Response List Camera Permissions Api V1 Cameras  Camera Id  Permissions Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Camera Permissions",
    "tags": [
     "cameras"
    ]
   },
   "post": {
    "description": "Assign or update a user's permission for a camera (owner or superuser).",
    "operationId": "assign_camera_permission_api_v1_cameras__camera_id__permissions_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CameraPermissionAssign"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CameraPermissionResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Assign Camera Permission",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/permissions/check": {
   "get": {
    "description": "Check if current user has permission to view/manage a camera.",
    "operationId": "check_camera_permission_api_v1_cameras__camera_id__permissions_check_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "require_manage",
      "required": false,
      "schema": {
       "default": false,
       "title": "Require Manage",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Check Camera Permission",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/permissions/{user_id}": {
   "delete": {
    "description": "Revoke a user's permission for a camera (owner or superuser).",
    "operationId": "revoke_camera_permission_api_v1_cameras__camera_id__permissions__user_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "user_id",
      "required": true,
      "schema": {
       "title": "User Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Revoke Camera Permission",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/probe-transport": {
   "post": {
    "description": "V-003: re-run the RTSPS reachability probe against the camera\nand update its ``transport_security`` policy in CameraConfig.\n\nUseful when the operator has:\n\n* just connected a camera that wasn't reachable at create time\n  (probe returned INCONCLUSIVE, policy stuck at ``rtsps_preferred``),\n* upgraded the camera's firmware to add RTSPS support,\n* swapped the underlying device while keeping the OpenNVR row.\n\nHonours the operator's existing explicit choice: if\n``transport_security_operator_set`` is True (the operator previously\nset the policy via PUT ``/cameras/{id}/transport-security``), this\nendpoint refreshes the probe result but leaves the policy intact.\nPass ``?reset_policy=true`` to clear the override AND let the probe\ndrive the value.",
    "operationId": "probe_camera_transport_api_v1_cameras__camera_id__probe_transport_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "description": "Override the RTSPS port for this probe. Useful when the camera multiplexes RTSPS onto a non-default port (e.g. 443). Omit to use the default port-selection rules.",
      "in": "query",
      "name": "port",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maximum": 65535,
         "minimum": 1,
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "description": "Override the RTSPS port for this probe. Useful when the camera multiplexes RTSPS onto a non-default port (e.g. 443). Omit to use the default port-selection rules.",
       "title": "Port"
      }
     },
     {
      "description": "If True, overwrite any operator-set transport_security policy with the probe-driven value. Default False preserves the operator's explicit choice.",
      "in": "query",
      "name": "reset_policy",
      "required": false,
      "schema": {
       "default": false,
       "description": "If True, overwrite any operator-set transport_security policy with the probe-driven value. Default False preserves the operator's explicit choice.",
       "title": "Reset Policy",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Probe Camera Transport",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/provision-mediamtx": {
   "post": {
    "description": "Manually provision a camera in MediaMTX.\n\nNVR policy: recording is mandatory, so ``enable_recording`` is forced on here\nregardless of the query param \u2014 a `curl` with ``?enable_recording=false``\nstill provisions with recording enabled. Enforcement also lives at the\nservice choke point (push_rtsp_stream); this keeps the response/logs honest.",
    "operationId": "provision_camera_mediamtx_api_v1_cameras__camera_id__provision_mediamtx_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "enable_recording",
      "required": false,
      "schema": {
       "default": false,
       "title": "Enable Recording",
       "type": "boolean"
      }
     },
     {
      "in": "query",
      "name": "rtsp_transport",
      "required": false,
      "schema": {
       "default": "tcp",
       "title": "Rtsp Transport",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "recording_segment_seconds",
      "required": false,
      "schema": {
       "default": 60,
       "title": "Recording Segment Seconds",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "recording_path",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Recording Path"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Provision Camera Mediamtx",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/ptz/move": {
   "post": {
    "description": "PTZ continuous move for a camera.\n\nUses the camera's stored ONVIF credentials from the database.\nx: Pan speed (-1.0 to 1.0, negative=left, positive=right)\ny: Tilt speed (-1.0 to 1.0, negative=down, positive=up)\nz: Zoom speed (-1.0 to 1.0, negative=zoom out, positive=zoom in)",
    "operationId": "ptz_move_api_v1_cameras__camera_id__ptz_move_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "x",
      "required": false,
      "schema": {
       "default": 0.0,
       "maximum": 1.0,
       "minimum": -1.0,
       "title": "X",
       "type": "number"
      }
     },
     {
      "in": "query",
      "name": "y",
      "required": false,
      "schema": {
       "default": 0.0,
       "maximum": 1.0,
       "minimum": -1.0,
       "title": "Y",
       "type": "number"
      }
     },
     {
      "in": "query",
      "name": "z",
      "required": false,
      "schema": {
       "default": 0.0,
       "maximum": 1.0,
       "minimum": -1.0,
       "title": "Z",
       "type": "number"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Ptz Move",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/ptz/stop": {
   "post": {
    "description": "Stop PTZ movement for a camera.\n\nUses the camera's stored ONVIF credentials from the database.",
    "operationId": "ptz_stop_api_v1_cameras__camera_id__ptz_stop_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Ptz Stop",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/reboot": {
   "post": {
    "description": "Reboot the camera. Write-gated (``camera_device.write``): recording\ndrops while the device restarts. Does NOT change any configuration.",
    "operationId": "reboot_camera_api_v1_cameras__camera_id__reboot_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Reboot Camera",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/security": {
   "get": {
    "description": "Read camera-side security posture (IP filter, cloud, login lock,\nprotocol/port state) plus the address this server reaches the camera from.",
    "operationId": "get_camera_security_api_v1_cameras__camera_id__security_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Camera Security",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/security/cloud": {
   "put": {
    "description": "Enable/disable the vendor P2P cloud tunnel (Hik-Connect / EZVIZ).",
    "operationId": "set_camera_cloud_api_v1_cameras__camera_id__security_cloud_put",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CloudUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set Camera Cloud",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/security/ip-filter": {
   "put": {
    "description": "Write the camera's IP filter.\n\nLOCKOUT-CAPABLE. The driver enforces the guardrails: an ``allow`` list is\nrefused if empty, this server's real source address is force-included and\nverified, the list is staged with the filter disabled and read back before\nbeing armed, and access is re-verified afterwards.",
    "operationId": "set_camera_ip_filter_api_v1_cameras__camera_id__security_ip_filter_put",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/IpFilterUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set Camera Ip Filter",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/services": {
   "get": {
    "description": "Read the camera's network services (UPnP, SNMP, FTP, DDNS, email, \u2026).",
    "operationId": "get_camera_services_api_v1_cameras__camera_id__services_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Camera Services",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/services/{service_key}": {
   "put": {
    "description": "Enable/disable one network service on the camera.",
    "operationId": "set_camera_service_api_v1_cameras__camera_id__services__service_key__put",
    "parameters": [
     {
      "in": "path",
      "name": "service_key",
      "required": true,
      "schema": {
       "title": "Service Key",
       "type": "string"
      }
     },
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ServiceUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set Camera Service",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/smart": {
   "get": {
    "description": "Read analytics detectors (line crossing, intrusion, face, tamper).",
    "operationId": "get_smart_api_v1_cameras__camera_id__smart_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Smart",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/smart/{detector_key}": {
   "put": {
    "description": "Enable/disable one analytics detector and set its sensitivity.",
    "operationId": "set_smart_api_v1_cameras__camera_id__smart__detector_key__put",
    "parameters": [
     {
      "in": "path",
      "name": "detector_key",
      "required": true,
      "schema": {
       "title": "Detector Key",
       "type": "string"
      }
     },
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SmartUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set Smart",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/snapshot": {
   "get": {
    "description": "One JPEG still of the camera's CURRENT view.\n\nBacks the App Catalog's geometry editors: an operator draws a\nrestricted zone / tripwire directly on what the camera actually\nsees, instead of hand-typing pixel coordinates. Served from the\nsame persistent capture pool inference uses (in-memory JPEG, no\ndisk round-trip), including the MediaMTX tap-URL resolution and\nstale-JWT self-heal.\n\nOwnership-checked like every camera read (owner or superuser);\n404 for unknown/unowned, 503 when no frame can be captured (camera\noffline / stream down) \u2014 the editor falls back to a plain grid.",
    "operationId": "get_camera_snapshot_api_v1_cameras__camera_id__snapshot_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Camera Snapshot",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/snapshot-still": {
   "get": {
    "description": "A JPEG still pulled straight from the camera via its native API.",
    "operationId": "get_camera_snapshot_still_api_v1_cameras__camera_id__snapshot_still_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Camera Snapshot Still",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/storage": {
   "get": {
    "description": "READ-ONLY SD/HDD storage status.",
    "operationId": "get_storage_api_v1_cameras__camera_id__storage_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Storage",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/stream/urls": {
   "get": {
    "operationId": "stream_urls_api_v1_cameras__camera_id__stream_urls_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": {
          "type": "string"
         },
         "title": "Response Stream Urls Api V1 Cameras  Camera Id  Stream Urls Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Stream Urls",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/test-connection": {
   "post": {
    "description": "Test camera connection.",
    "operationId": "test_camera_connection_api_v1_cameras__camera_id__test_connection_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Test Camera Connection",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/time": {
   "get": {
    "description": "Read the camera clock (mode, UTC/local time, timezone, NTP server).",
    "operationId": "get_time_api_v1_cameras__camera_id__time_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Time",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/time/ntp": {
   "put": {
    "description": "Point the camera at an NTP server and switch it to NTP time.",
    "operationId": "set_time_ntp_api_v1_cameras__camera_id__time_ntp_put",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/NtpRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set Time Ntp",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/time/sync-manual": {
   "post": {
    "description": "Push this server's current UTC to the camera (fixes a wrong clock).",
    "operationId": "sync_time_manual_api_v1_cameras__camera_id__time_sync_manual_post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ManualSyncRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Sync Time Manual",
    "tags": [
     "camera-settings"
    ]
   }
  },
  "/api/v1/cameras/{camera_id}/transport-security": {
   "put": {
    "description": "V-003: explicitly set the camera's transport_security policy.\n\nUse to:\n\n* Lock a camera at ``rtsps_required`` so the stream service refuses\n  plaintext fallback even if the camera temporarily fails the\n  probe (V-003 strict mode).\n* Mark a legacy camera as ``plaintext_allowed`` so the UI stops\n  flagging it as a posture warning.\n* Restore a custom-port camera to ``rtsps_preferred`` after a\n  misleading probe.\n\nSets ``transport_security_operator_set=True`` so subsequent calls\nto POST ``/probe-transport`` preserve the operator's choice.",
    "operationId": "set_camera_transport_security_api_v1_cameras__camera_id__transport_security_put",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TransportSecurityUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set Camera Transport Security",
    "tags": [
     "cameras"
    ]
   }
  },
  "/api/v1/cloud-inference/infer": {
   "post": {
    "description": "Execute synchronous cloud AI inference.\n\n- **model_id**: CloudProviderModel ID to use\n- **inputs**: Inference inputs (e.g., {\"image\": \"https://example.com/image.jpg\"})\n- **parameters**: Optional inference parameters (e.g., {\"num_beams\": 5})\n\nReturns inference result immediately (blocks until complete).",
    "operationId": "run_inference_api_v1_cloud_inference_infer_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CloudInferenceRequest"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CloudInferenceResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Run Inference",
    "tags": [
     "Cloud Inference"
    ]
   }
  },
  "/api/v1/cloud-inference/jobs": {
   "get": {
    "description": "List async inference jobs for the current user.\n\n- **status_filter**: Filter by status (queued, processing, completed, failed)\n- **limit**: Max number of jobs to return (default 50)",
    "operationId": "list_jobs_api_v1_cloud_inference_jobs_get",
    "parameters": [
     {
      "in": "query",
      "name": "status_filter",
      "required": false,
      "schema": {
       "title": "Status Filter",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "$ref": "#/components/schemas/AIInferenceJobResponse"
         },
         "title": "Response List Jobs Api V1 Cloud Inference Jobs Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Jobs",
    "tags": [
     "Cloud Inference"
    ]
   },
   "post": {
    "description": "Create an asynchronous inference job.\n\nReturns immediately with a job ID. Use GET /jobs/{job_id} to check status.",
    "operationId": "create_async_job_api_v1_cloud_inference_jobs_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AIInferenceJobCreate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AIInferenceJobResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create Async Job",
    "tags": [
     "Cloud Inference"
    ]
   }
  },
  "/api/v1/cloud-inference/jobs/{job_id}": {
   "get": {
    "description": "Get the status of an async inference job.",
    "operationId": "get_job_status_api_v1_cloud_inference_jobs__job_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "job_id",
      "required": true,
      "schema": {
       "title": "Job Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/AIInferenceJobResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Job Status",
    "tags": [
     "Cloud Inference"
    ]
   }
  },
  "/api/v1/cloud-inference/results": {
   "get": {
    "description": "List inference results for the current user.\n\n- **limit**: Max number of results to return (default 50)",
    "operationId": "list_inference_results_api_v1_cloud_inference_results_get",
    "parameters": [
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "$ref": "#/components/schemas/CloudInferenceResponse"
         },
         "title": "Response List Inference Results Api V1 Cloud Inference Results Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Inference Results",
    "tags": [
     "Cloud Inference"
    ]
   }
  },
  "/api/v1/cloud-inference/results/{result_id}": {
   "get": {
    "description": "Get a specific inference result by ID.",
    "operationId": "get_inference_result_api_v1_cloud_inference_results__result_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "result_id",
      "required": true,
      "schema": {
       "title": "Result Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CloudInferenceResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Inference Result",
    "tags": [
     "Cloud Inference"
    ]
   }
  },
  "/api/v1/cloud-providers/credentials": {
   "get": {
    "description": "List all cloud provider credentials for the current user (tokens not returned).",
    "operationId": "list_credentials_api_v1_cloud_providers_credentials_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "$ref": "#/components/schemas/CloudProviderCredentialResponse"
         },
         "title": "Response List Credentials Api V1 Cloud Providers Credentials Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Credentials",
    "tags": [
     "Cloud Providers"
    ]
   },
   "post": {
    "description": "Store a new cloud provider credential (encrypted at rest).\n\n- **provider**: Provider name (e.g., 'huggingface')\n- **token**: API token (will be encrypted before storage)\n- **account_info**: Optional metadata (e.g., account ID, email)",
    "operationId": "create_credential_api_v1_cloud_providers_credentials_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CloudProviderCredentialCreate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CloudProviderCredentialResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create Credential",
    "tags": [
     "Cloud Providers"
    ]
   }
  },
  "/api/v1/cloud-providers/credentials/{credential_id}": {
   "delete": {
    "description": "Delete a cloud provider credential.",
    "operationId": "delete_credential_api_v1_cloud_providers_credentials__credential_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "credential_id",
      "required": true,
      "schema": {
       "title": "Credential Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete Credential",
    "tags": [
     "Cloud Providers"
    ]
   }
  },
  "/api/v1/cloud-providers/models": {
   "get": {
    "description": "List all configured cloud provider models for the current user.",
    "operationId": "list_model_configs_api_v1_cloud_providers_models_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "$ref": "#/components/schemas/CloudProviderModelResponse"
         },
         "title": "Response List Model Configs Api V1 Cloud Providers Models Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Model Configs",
    "tags": [
     "Cloud Providers"
    ]
   },
   "post": {
    "description": "Configure a cloud provider model for use.\n\n- **name**: Friendly name for the model\n- **provider**: Provider name (must match credential provider)\n- **credential_id**: UUID of the credential to use\n- **model_id**: Model identifier (e.g., 'Salesforce/blip-image-captioning-base')\n- **task**: Task type (e.g., 'image-classification', 'object-detection')\n- **config**: Optional model configuration as JSON string\n- **enabled**: Whether the model is enabled (default: true)",
    "operationId": "create_model_config_api_v1_cloud_providers_models_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CloudProviderModelCreate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CloudProviderModelResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create Model Config",
    "tags": [
     "Cloud Providers"
    ]
   }
  },
  "/api/v1/cloud-providers/models/{model_id}": {
   "delete": {
    "description": "Delete a model configuration.",
    "operationId": "delete_model_config_api_v1_cloud_providers_models__model_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete Model Config",
    "tags": [
     "Cloud Providers"
    ]
   },
   "get": {
    "description": "Get details of a specific model configuration.",
    "operationId": "get_model_config_api_v1_cloud_providers_models__model_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "model_id",
      "required": true,
      "schema": {
       "title": "Model Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CloudProviderModelResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Model Config",
    "tags": [
     "Cloud Providers"
    ]
   }
  },
  "/api/v1/cloud-providers/quotas/{provider}": {
   "get": {
    "description": "Get current quota usage and limits for a provider.",
    "operationId": "get_quota_usage_api_v1_cloud_providers_quotas__provider__get",
    "parameters": [
     {
      "in": "path",
      "name": "provider",
      "required": true,
      "schema": {
       "title": "Provider",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TenantQuotaResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Quota Usage",
    "tags": [
     "Cloud Providers"
    ]
   },
   "patch": {
    "description": "Update quota limits for a provider.\n\nRequires admin privileges.",
    "operationId": "update_quota_api_v1_cloud_providers_quotas__provider__patch",
    "parameters": [
     {
      "in": "path",
      "name": "provider",
      "required": true,
      "schema": {
       "title": "Provider",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TenantQuotaUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/TenantQuotaResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Quota",
    "tags": [
     "Cloud Providers"
    ]
   }
  },
  "/api/v1/cloud-streaming/presets": {
   "get": {
    "description": "Get available server type presets (RTMP, RTMPS, SRT).",
    "operationId": "get_server_presets_api_v1_cloud_streaming_presets_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Server Presets",
    "tags": [
     "cloud-streaming"
    ]
   }
  },
  "/api/v1/cloud-streaming/status": {
   "get": {
    "description": "Get status of all active streams.",
    "operationId": "get_all_stream_statuses_api_v1_cloud_streaming_status_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get All Stream Statuses",
    "tags": [
     "cloud-streaming"
    ]
   }
  },
  "/api/v1/cloud-streaming/targets": {
   "get": {
    "description": "List all configured cloud stream targets.",
    "operationId": "list_stream_targets_api_v1_cloud_streaming_targets_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Stream Targets",
    "tags": [
     "cloud-streaming"
    ]
   },
   "post": {
    "description": "Create or update a cloud stream target. Multiple targets per camera are supported.",
    "operationId": "create_or_update_stream_target_api_v1_cloud_streaming_targets_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CloudStreamTargetCreate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create Or Update Stream Target",
    "tags": [
     "cloud-streaming"
    ]
   }
  },
  "/api/v1/cloud-streaming/targets/{target_id}": {
   "delete": {
    "description": "Delete a cloud stream target and stop streaming.",
    "operationId": "delete_stream_target_api_v1_cloud_streaming_targets__target_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "target_id",
      "required": true,
      "schema": {
       "title": "Target Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete Stream Target",
    "tags": [
     "cloud-streaming"
    ]
   },
   "get": {
    "description": "Get a specific cloud stream target.",
    "operationId": "get_stream_target_api_v1_cloud_streaming_targets__target_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "target_id",
      "required": true,
      "schema": {
       "title": "Target Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Stream Target",
    "tags": [
     "cloud-streaming"
    ]
   }
  },
  "/api/v1/cloud-streaming/targets/{target_id}/start": {
   "post": {
    "description": "Start streaming to a configured target.",
    "operationId": "start_stream_api_v1_cloud_streaming_targets__target_id__start_post",
    "parameters": [
     {
      "in": "path",
      "name": "target_id",
      "required": true,
      "schema": {
       "title": "Target Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Start Stream",
    "tags": [
     "cloud-streaming"
    ]
   }
  },
  "/api/v1/cloud-streaming/targets/{target_id}/status": {
   "get": {
    "description": "Get the current status of a stream target.",
    "operationId": "get_stream_status_api_v1_cloud_streaming_targets__target_id__status_get",
    "parameters": [
     {
      "in": "path",
      "name": "target_id",
      "required": true,
      "schema": {
       "title": "Target Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Stream Status",
    "tags": [
     "cloud-streaming"
    ]
   }
  },
  "/api/v1/cloud-streaming/targets/{target_id}/stop": {
   "post": {
    "description": "Stop streaming to a target.",
    "operationId": "stop_stream_api_v1_cloud_streaming_targets__target_id__stop_post",
    "parameters": [
     {
      "in": "path",
      "name": "target_id",
      "required": true,
      "schema": {
       "title": "Target Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Stop Stream",
    "tags": [
     "cloud-streaming"
    ]
   }
  },
  "/api/v1/cloud/settings": {
   "get": {
    "operationId": "get_cloud_settings_api_v1_cloud_settings_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Cloud Settings",
    "tags": [
     "cloud"
    ]
   },
   "put": {
    "operationId": "put_cloud_settings_api_v1_cloud_settings_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CloudSettings"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Put Cloud Settings",
    "tags": [
     "cloud"
    ]
   }
  },
  "/api/v1/cloud/test": {
   "post": {
    "description": "Lightweight connectivity test to the configured endpoints (optional).\nFor now, just returns stored URLs; future versions may attempt real network calls.",
    "operationId": "test_cloud_connectivity_api_v1_cloud_test_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Test Cloud Connectivity",
    "tags": [
     "cloud"
    ]
   }
  },
  "/api/v1/compliance/access-audit": {
   "get": {
    "description": "Get recent camera access audit logs.\nFilters for camera-related actions (view, stream, playback).",
    "operationId": "get_access_audit_api_v1_compliance_access_audit_get",
    "parameters": [
     {
      "description": "Maximum number of logs to return",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 100,
       "description": "Maximum number of logs to return",
       "maximum": 500,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "description": "Filter by camera ID",
      "in": "query",
      "name": "camera_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "description": "Filter by camera ID",
       "title": "Camera Id"
      }
     },
     {
      "description": "Filter by action (e.g., 'camera.view', 'stream.start')",
      "in": "query",
      "name": "action_filter",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Filter by action (e.g., 'camera.view', 'stream.start')",
       "title": "Action Filter"
      }
     },
     {
      "description": "Number of days to look back",
      "in": "query",
      "name": "days",
      "required": false,
      "schema": {
       "default": 7,
       "description": "Number of days to look back",
       "maximum": 90,
       "minimum": 1,
       "title": "Days",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Access Audit",
    "tags": [
     "compliance"
    ]
   }
  },
  "/api/v1/compliance/export": {
   "get": {
    "description": "Export compliance data as CSV file.\nIncludes summary stats and recording coverage for the last N days.",
    "operationId": "export_compliance_csv_api_v1_compliance_export_get",
    "parameters": [
     {
      "description": "Days of coverage to export",
      "in": "query",
      "name": "days",
      "required": false,
      "schema": {
       "default": 30,
       "description": "Days of coverage to export",
       "maximum": 90,
       "minimum": 1,
       "title": "Days",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Export Compliance Csv",
    "tags": [
     "compliance"
    ]
   }
  },
  "/api/v1/compliance/recording-coverage": {
   "get": {
    "description": "Get per-camera recording coverage for the last N days.\nReturns daily recording counts and total duration per camera per day.",
    "operationId": "get_recording_coverage_api_v1_compliance_recording_coverage_get",
    "parameters": [
     {
      "description": "Number of days to analyze",
      "in": "query",
      "name": "days",
      "required": false,
      "schema": {
       "default": 30,
       "description": "Number of days to analyze",
       "maximum": 90,
       "minimum": 1,
       "title": "Days",
       "type": "integer"
      }
     },
     {
      "description": "Filter by specific camera ID",
      "in": "query",
      "name": "camera_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "description": "Filter by specific camera ID",
       "title": "Camera Id"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Recording Coverage",
    "tags": [
     "compliance"
    ]
   }
  },
  "/api/v1/compliance/security-check": {
   "get": {
    "description": "Lite, local \u00a7889 / security posture check computed from the camera\ninventory OpenNVR already has (no scanning, nothing leaves the box). Flags\ncovered-vendor cameras (public FCC Covered List), public-IP exposure,\nplaintext streams, and default usernames. For a formal, audit-ready \u00a7889\nattestation (OEM-rebrand resolution, CVE cross-reference, signed report),\nOpenNVR Scout is the full assessment this points to.",
    "operationId": "get_security_check_api_v1_compliance_security_check_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Security Check",
    "tags": [
     "compliance"
    ]
   }
  },
  "/api/v1/compliance/summary": {
   "get": {
    "description": "Get overall compliance summary including:\n- Total cameras\n- Online cameras (streaming data > 0 bytes)\n- Degraded cameras (unused in simplified logic, or specific error states)\n- Offline cameras (no data streaming)\n- Recording enabled count\n- Retention period (Configured Policy)\n- Storage usage (calculated from filesystem)",
    "operationId": "get_compliance_summary_api_v1_compliance_summary_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Compliance Summary",
    "tags": [
     "compliance"
    ]
   }
  },
  "/api/v1/connect": {
   "post": {
    "description": "Connect to ONVIF device and get all profiles with stream URIs.\n\nUses HTTP Digest authentication which is compatible with Hikvision and most devices.\nReturns device info and all available profiles with their RTSP stream URIs.",
    "operationId": "connect_device_api_v1_connect_post",
    "parameters": [
     {
      "in": "query",
      "name": "ip",
      "required": true,
      "schema": {
       "title": "Ip",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "port",
      "required": false,
      "schema": {
       "default": 80,
       "maximum": 65535,
       "minimum": 1,
       "title": "Port",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "username",
      "required": true,
      "schema": {
       "title": "Username",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "password",
      "required": true,
      "schema": {
       "title": "Password",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Connect Device",
    "tags": [
     "onvif"
    ]
   }
  },
  "/api/v1/device-firewall/devices": {
   "get": {
    "operationId": "list_devices_api_v1_device_firewall_devices_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Devices",
    "tags": [
     "device-firewall"
    ]
   }
  },
  "/api/v1/device-firewall/devices/{device_id}": {
   "delete": {
    "operationId": "delete_device_api_v1_device_firewall_devices__device_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "device_id",
      "required": true,
      "schema": {
       "title": "Device Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete Device",
    "tags": [
     "device-firewall"
    ]
   }
  },
  "/api/v1/device-firewall/devices/{device_id}/approve": {
   "post": {
    "operationId": "approve_device_api_v1_device_firewall_devices__device_id__approve_post",
    "parameters": [
     {
      "in": "path",
      "name": "device_id",
      "required": true,
      "schema": {
       "title": "Device Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "anyOf": [
         {
          "$ref": "#/components/schemas/DeviceLabel"
         },
         {
          "type": "null"
         }
        ],
        "title": "Payload"
       }
      }
     }
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Approve Device",
    "tags": [
     "device-firewall"
    ]
   }
  },
  "/api/v1/device-firewall/devices/{device_id}/block": {
   "post": {
    "operationId": "block_device_api_v1_device_firewall_devices__device_id__block_post",
    "parameters": [
     {
      "in": "path",
      "name": "device_id",
      "required": true,
      "schema": {
       "title": "Device Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Block Device",
    "tags": [
     "device-firewall"
    ]
   }
  },
  "/api/v1/device-firewall/enforcement": {
   "put": {
    "description": "Turn enforcement on/off. Returns the *effective* state \u2014 the env\nbreak-glass can force it off even when the admin asks for on.",
    "operationId": "set_enforcement_api_v1_device_firewall_enforcement_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/EnforcementUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set Enforcement",
    "tags": [
     "device-firewall"
    ]
   }
  },
  "/api/v1/device-firewall/status": {
   "get": {
    "description": "This caller's own state \u2014 reachable even when blocked, so the UI can tell\nthe user their browser is pending and give an admin something to identify it\nby. ``device_id`` is the row an admin approves; ``device_ip`` is metadata.",
    "operationId": "my_status_api_v1_device_firewall_status_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "My Status",
    "tags": [
     "device-firewall"
    ]
   }
  },
  "/api/v1/discover": {
   "get": {
    "description": "Discover ONVIF cameras via unicast subnet scan (works in Docker bridge mode).\n\nScans all configured Camera LAN subnets under one concurrency bound. An\noptional ``cidr`` parameter (repeatable) overrides the configured list for\nthis scan only \u2014 each must be an internal (RFC1918-class) range, but may lie\noutside the configured Camera LAN: the caller is a superuser looking for a\ncamera before committing a Camera LAN change, and adding a camera found\noutside the boundary still requires persisting that change first (the\nconnect/add flows keep enforcing the configured subnets). Multicast\nWS-Discovery runs as a best-effort fallback.",
    "operationId": "discover_api_v1_discover_get",
    "parameters": [
     {
      "description": "One or more subnet CIDRs to scan (e.g. cidr=192.168.1.0/24&cidr=10.0.0.0/24). Falls back to all subnets configured in Camera LAN settings.",
      "in": "query",
      "name": "cidr",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "items": {
          "type": "string"
         },
         "type": "array"
        },
        {
         "type": "null"
        }
       ],
       "description": "One or more subnet CIDRs to scan (e.g. cidr=192.168.1.0/24&cidr=10.0.0.0/24). Falls back to all subnets configured in Camera LAN settings.",
       "title": "Cidr"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Discover",
    "tags": [
     "onvif"
    ]
   }
  },
  "/api/v1/discover/plan": {
   "get": {
    "description": "Return the subnets a discovery scan would cover, without scanning.\n\nLets the UI show \"Scanning 192.168.1.0/24 \u00b7 auto-detected\" while the actual\n(slow) scan is still running, and render a friendly prompt instead of an\nerror when nothing is configured or detectable (``scan_cidrs`` comes back\nempty rather than a 400).\n\n``detected_cidrs`` lists ALL of the host's detected LAN subnets regardless\nof the configured Camera LAN, so the UI can always offer \"scan a host\nnetwork\" \u2014 an operator hunting for a camera on a second NIC shouldn't have\nto know its range by heart. Detection is Docker-aware (bridge ignored,\nhost IPs come from OPENNVR_HOST_IP/OPENNVR_LAN_IPS).",
    "operationId": "discover_plan_api_v1_discover_plan_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Discover Plan",
    "tags": [
     "onvif"
    ]
   }
  },
  "/api/v1/events": {
   "get": {
    "description": "Query visits/alarms/alerts, newest first.\n\nTime filters use the OVERLAP rule \u2014 an event counts if any part of it\nintersects [from, to) \u2014 because \"who was here 3-4pm\" must include the\nvisit that started 14:58 and left 15:03.\n\nPaging is ``skip``/``limit`` (the house shape \u2014 audit-logs, cameras,\nusers). ``limit`` is now VALIDATED at the 500 the service always\nclamped to: silently trimming a larger request was harmless while\nnothing paged, but a client that believes it asked for 1000 and then\nasks for skip=1000 would step clean over rows 500-999. A 422 is the\nhonest answer.\n\n``skip`` is capped because page numbers invite a \"last page\" jump,\nand the last page of a large scoped set is the single most expensive\nquery this endpoint can be asked for.\n\nTwo counts, deliberately different:\n  count  \u2014 rows in THIS page (unchanged; every existing client\n           ignores it, which is why it stays rather than moving).\n  total  \u2014 rows matching these filters and this caller's scope, for\n           the pager's \"1-25 of 312\".",
    "operationId": "list_events_api_v1_events_get",
    "parameters": [
     {
      "in": "query",
      "name": "camera_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Camera Id"
      }
     },
     {
      "in": "query",
      "name": "label",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Label"
      }
     },
     {
      "in": "query",
      "name": "source",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Source"
      }
     },
     {
      "in": "query",
      "name": "plate",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Plate"
      }
     },
     {
      "in": "query",
      "name": "has_plate",
      "required": false,
      "schema": {
       "default": false,
       "title": "Has Plate",
       "type": "boolean"
      }
     },
     {
      "in": "query",
      "name": "from",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "format": "date-time",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "From"
      }
     },
     {
      "in": "query",
      "name": "to",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "format": "date-time",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "To"
      }
     },
     {
      "in": "query",
      "name": "skip",
      "required": false,
      "schema": {
       "default": 0,
       "maximum": 100000,
       "minimum": 0,
       "title": "Skip",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 100,
       "maximum": 500,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Events",
    "tags": [
     "timeline"
    ]
   }
  },
  "/api/v1/events/gate-occupancy": {
   "get": {
    "description": "How many vehicles are inside right now (last gate read within\nthe window was an entry). Windowed so missed exits age out.",
    "operationId": "get_gate_occupancy_api_v1_events_gate_occupancy_get",
    "parameters": [
     {
      "in": "query",
      "name": "in_cameras",
      "required": false,
      "schema": {
       "default": "",
       "title": "In Cameras",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "out_cameras",
      "required": false,
      "schema": {
       "default": "",
       "title": "Out Cameras",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "hours",
      "required": false,
      "schema": {
       "default": 24,
       "title": "Hours",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Gate Occupancy",
    "tags": [
     "timeline"
    ]
   }
  },
  "/api/v1/events/plate-sessions": {
   "get": {
    "description": "Gate in / gate out history for one plate. ``in_cameras`` /\n``out_cameras`` are comma-separated camera ids \u2014 which camera is\nwhich gate lives in the providing app's config, so the caller\npasses the sets and this stays stateless. Owner-scoped.",
    "operationId": "get_plate_sessions_api_v1_events_plate_sessions_get",
    "parameters": [
     {
      "in": "query",
      "name": "plate",
      "required": true,
      "schema": {
       "title": "Plate",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "in_cameras",
      "required": false,
      "schema": {
       "default": "",
       "title": "In Cameras",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "out_cameras",
      "required": false,
      "schema": {
       "default": "",
       "title": "Out Cameras",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Plate Sessions",
    "tags": [
     "timeline"
    ]
   }
  },
  "/api/v1/events/plate-stats": {
   "get": {
    "description": "Aggregates for the Vehicles page (plate reads over the last\n``days``): totals, unique plates, per-camera and per-day counts.\nOwner-scoped like /events; superusers see the fleet.",
    "operationId": "get_plate_stats_api_v1_events_plate_stats_get",
    "parameters": [
     {
      "in": "query",
      "name": "days",
      "required": false,
      "schema": {
       "default": 7,
       "title": "Days",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Plate Stats",
    "tags": [
     "timeline"
    ]
   }
  },
  "/api/v1/events/plate-summary": {
   "get": {
    "description": "All-time history for ONE plate \u2014 the Vehicles page drill-down:\nfirst seen, last seen, total reads, per-camera counts. Owner-scoped\nlike /events; superusers see the fleet.",
    "operationId": "get_plate_summary_api_v1_events_plate_summary_get",
    "parameters": [
     {
      "in": "query",
      "name": "plate",
      "required": true,
      "schema": {
       "title": "Plate",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Plate Summary",
    "tags": [
     "timeline"
    ]
   }
  },
  "/api/v1/events/vehicle-report": {
   "get": {
    "description": "One calendar month of vehicle movement, aggregated for the\nprintable monthly report. Owner-scoped like /events.",
    "operationId": "get_vehicle_report_api_v1_events_vehicle_report_get",
    "parameters": [
     {
      "in": "query",
      "name": "year",
      "required": true,
      "schema": {
       "title": "Year",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "month",
      "required": true,
      "schema": {
       "title": "Month",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Vehicle Report",
    "tags": [
     "timeline"
    ]
   }
  },
  "/api/v1/events/ws-ticket": {
   "post": {
    "description": "Mint a short-lived, single-use ticket for opening the events WebSocket.\n\nA browser cannot set an Authorization header on a WebSocket, so it\ncalls this authenticated endpoint first, then opens\n``/events/ws?ticket=<ticket>``.\n\nThree credentials are accepted, and they yield different tickets:\n\n* a user JWT \u2192 a ticket bound to that user; the stream is scoped to\n  the cameras they may see (``visible_camera_ids``);\n* the deployment's ``INTERNAL_API_KEY`` \u2192 a SERVICE ticket, unscoped.\n  For trusted in-stack consumers only: the camera agent relays core's\n  overlay tracks to its own viewers and applies its own per-viewer\n  scope, the same way it does for everything else it shows;\n* an app key \u2192 refused (403). An installed app is not a platform\n  service; its own view of the bus is what the SDK gives it.",
    "operationId": "create_ws_ticket_api_v1_events_ws_ticket_post",
    "parameters": [
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create Ws Ticket"
   }
  },
  "/api/v1/events/{event_id}/evidence": {
   "get": {
    "description": "The visit's best-frame JPEG \u2014 the sharpest look Tier-0 had at it.",
    "operationId": "get_event_evidence_api_v1_events__event_id__evidence_get",
    "parameters": [
     {
      "in": "path",
      "name": "event_id",
      "required": true,
      "schema": {
       "title": "Event Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Event Evidence",
    "tags": [
     "timeline"
    ]
   }
  },
  "/api/v1/events/{event_id}/plate-evidence": {
   "get": {
    "description": "The crop this row's PLATE was read from (#382).\n\nDistinct from the best-frame evidence above: multi-frame OCR reads\nplate-candidate crops, and the vehicle-best frame is \u2014 by\nconstruction \u2014 usually the one where the plate has left the crop.\n404 when the read came from the evidence frame itself or predates\nthe column; callers fall back to ``/evidence``.",
    "operationId": "get_event_plate_evidence_api_v1_events__event_id__plate_evidence_get",
    "parameters": [
     {
      "in": "path",
      "name": "event_id",
      "required": true,
      "schema": {
       "title": "Event Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Event Plate Evidence",
    "tags": [
     "timeline"
    ]
   }
  },
  "/api/v1/events/{event_id}/plate-frame": {
   "get": {
    "description": "The frame this row's plate crop was cut from.\n\n``/plate-evidence`` is the plate rectangle; this is everything around\nit \u2014 the vehicle the number belongs to, at the moment it was read.\nDistinct from ``/evidence`` and ``/scene-evidence``, which show the\nvisit's best-thumbnail moment and can be a different car when track\nassociation merged two vehicles into one visit. 404 for rows read\nbefore the column existed; callers fall back to ``/evidence``.",
    "operationId": "get_event_plate_frame_api_v1_events__event_id__plate_frame_get",
    "parameters": [
     {
      "in": "path",
      "name": "event_id",
      "required": true,
      "schema": {
       "title": "Event Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Event Plate Frame",
    "tags": [
     "timeline"
    ]
   }
  },
  "/api/v1/events/{event_id}/scene-evidence": {
   "get": {
    "description": "The whole frame the best crop was taken from.\n\n``/evidence`` is framed for the subject and cannot show the lane, the\ngate, or the car parked next to it; this is the same moment, uncropped.\n404 when the pipeline sent no scene frame or the row predates the\ncolumn \u2014 callers fall back to ``/evidence``.",
    "operationId": "get_event_scene_evidence_api_v1_events__event_id__scene_evidence_get",
    "parameters": [
     {
      "in": "path",
      "name": "event_id",
      "required": true,
      "schema": {
       "title": "Event Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Event Scene Evidence",
    "tags": [
     "timeline"
    ]
   }
  },
  "/api/v1/firmware/apply-updates": {
   "post": {
    "description": "Apply available updates (requires elevated privileges).",
    "operationId": "apply_updates_api_v1_firmware_apply_updates_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Apply Updates",
    "tags": [
     "firmware"
    ]
   }
  },
  "/api/v1/firmware/auto-update": {
   "get": {
    "description": "Get auto-update configuration.",
    "operationId": "get_auto_update_settings_endpoint_api_v1_firmware_auto_update_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Auto Update Settings Endpoint",
    "tags": [
     "firmware"
    ]
   },
   "put": {
    "description": "Update auto-update configuration.",
    "operationId": "update_auto_update_settings_api_v1_firmware_auto_update_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Payload",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Auto Update Settings",
    "tags": [
     "firmware"
    ]
   }
  },
  "/api/v1/firmware/check-updates": {
   "post": {
    "description": "Manually trigger update check.",
    "operationId": "check_updates_manual_api_v1_firmware_check_updates_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Check Updates Manual",
    "tags": [
     "firmware"
    ]
   }
  },
  "/api/v1/firmware/system-info": {
   "get": {
    "description": "Get system information (OS, kernel, BIOS, etc.).",
    "operationId": "get_system_info_api_v1_firmware_system_info_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get System Info",
    "tags": [
     "firmware"
    ]
   }
  },
  "/api/v1/firmware/update-status": {
   "get": {
    "description": "Check for available security/system updates.",
    "operationId": "get_update_status_api_v1_firmware_update_status_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Update Status",
    "tags": [
     "firmware"
    ]
   }
  },
  "/api/v1/general/window-settings": {
   "get": {
    "description": "Read the Live View window-layout preferences (any authenticated user).",
    "operationId": "get_window_settings_api_v1_general_window_settings_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Window Settings",
    "tags": [
     "window-settings"
    ]
   },
   "put": {
    "description": "Update the Live View window-layout preferences.",
    "operationId": "update_window_settings_api_v1_general_window_settings_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/WindowDivisionSettings"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Window Settings",
    "tags": [
     "window-settings"
    ]
   }
  },
  "/api/v1/guardscan/export": {
   "get": {
    "description": "The screenings as CSV, for an audit file or a spreadsheet.",
    "operationId": "export_screenings_api_v1_guardscan_export_get",
    "parameters": [
     {
      "in": "query",
      "name": "days",
      "required": false,
      "schema": {
       "default": 30,
       "maximum": 92,
       "minimum": 1,
       "title": "Days",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "camera_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Camera Id"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Export Screenings",
    "tags": [
     "guard-scan"
    ]
   }
  },
  "/api/v1/guardscan/report": {
   "get": {
    "description": "How consistently the procedure was followed, by period and guard.\n\nBuckets are formed in the operator's LOCAL time, as the browser\nreports it: a shift that runs to 01:00 belongs to the day the guard\nthinks it does, not to whatever UTC says.",
    "operationId": "compliance_report_api_v1_guardscan_report_get",
    "parameters": [
     {
      "in": "query",
      "name": "days",
      "required": false,
      "schema": {
       "default": 7,
       "maximum": 92,
       "minimum": 1,
       "title": "Days",
       "type": "integer"
      }
     },
     {
      "description": "day|week|month",
      "in": "query",
      "name": "period",
      "required": false,
      "schema": {
       "default": "day",
       "description": "day|week|month",
       "title": "Period",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "camera_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Camera Id"
      }
     },
     {
      "in": "query",
      "name": "tz_offset_minutes",
      "required": false,
      "schema": {
       "default": 0,
       "title": "Tz Offset Minutes",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Compliance Report",
    "tags": [
     "guard-scan"
    ]
   }
  },
  "/api/v1/guardscan/screenings": {
   "get": {
    "description": "Screenings, newest first \u2014 the searchable history.",
    "operationId": "list_screenings_api_v1_guardscan_screenings_get",
    "parameters": [
     {
      "in": "query",
      "name": "camera_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Camera Id"
      }
     },
     {
      "description": "compliant|partial|incomplete|no_scan",
      "in": "query",
      "name": "verdict",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "compliant|partial|incomplete|no_scan",
       "title": "Verdict"
      }
     },
     {
      "description": "'problems' for everything that was not a complete scan, 'compliant' for the clean ones",
      "in": "query",
      "name": "outcome",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "'problems' for everything that was not a complete scan, 'compliant' for the clean ones",
       "title": "Outcome"
      }
     },
     {
      "description": "Guard name or key",
      "in": "query",
      "name": "guard",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Guard name or key",
       "title": "Guard"
      }
     },
     {
      "description": "Only scanner-flagged",
      "in": "query",
      "name": "flagged",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "boolean"
        },
        {
         "type": "null"
        }
       ],
       "description": "Only scanner-flagged",
       "title": "Flagged"
      }
     },
     {
      "in": "query",
      "name": "from",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "From"
      }
     },
     {
      "in": "query",
      "name": "to",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "To"
      }
     },
     {
      "in": "query",
      "name": "skip",
      "required": false,
      "schema": {
       "default": 0,
       "maximum": 100000,
       "minimum": 0,
       "title": "Skip",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "maximum": 200,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Screenings",
    "tags": [
     "guard-scan"
    ]
   }
  },
  "/api/v1/guardscan/screenings/{screening_id}/images/{name}": {
   "get": {
    "description": "One evidence photo from a screening \u2014 who was scanned, and by whom.",
    "operationId": "get_screening_image_api_v1_guardscan_screenings__screening_id__images__name__get",
    "parameters": [
     {
      "in": "path",
      "name": "screening_id",
      "required": true,
      "schema": {
       "title": "Screening Id",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "name",
      "required": true,
      "schema": {
       "title": "Name",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Screening Image",
    "tags": [
     "guard-scan"
    ]
   }
  },
  "/api/v1/integrations": {
   "get": {
    "description": "List all configured integrations.",
    "operationId": "get_integrations_api_v1_integrations_get",
    "parameters": [
     {
      "in": "query",
      "name": "skip",
      "required": false,
      "schema": {
       "default": 0,
       "title": "Skip",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 100,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "items": {
          "$ref": "#/components/schemas/IntegrationRead"
         },
         "title": "Response Get Integrations Api V1 Integrations Get",
         "type": "array"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Integrations",
    "tags": [
     "integrations"
    ]
   },
   "post": {
    "description": "Create a new integration.",
    "operationId": "create_integration_api_v1_integrations_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/IntegrationCreate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/IntegrationRead"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create Integration",
    "tags": [
     "integrations"
    ]
   }
  },
  "/api/v1/integrations/{integration_id}": {
   "delete": {
    "description": "Delete an integration.",
    "operationId": "delete_integration_api_v1_integrations__integration_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "integration_id",
      "required": true,
      "schema": {
       "title": "Integration Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete Integration",
    "tags": [
     "integrations"
    ]
   },
   "get": {
    "description": "Get specific integration details.",
    "operationId": "get_integration_api_v1_integrations__integration_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "integration_id",
      "required": true,
      "schema": {
       "title": "Integration Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/IntegrationRead"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Integration",
    "tags": [
     "integrations"
    ]
   },
   "put": {
    "description": "Update an integration.",
    "operationId": "update_integration_api_v1_integrations__integration_id__put",
    "parameters": [
     {
      "in": "path",
      "name": "integration_id",
      "required": true,
      "schema": {
       "title": "Integration Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/IntegrationUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/IntegrationRead"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Integration",
    "tags": [
     "integrations"
    ]
   }
  },
  "/api/v1/integrations/{integration_id}/test": {
   "post": {
    "description": "Test an integration by sending a dummy event.",
    "operationId": "test_integration_api_v1_integrations__integration_id__test_post",
    "parameters": [
     {
      "in": "path",
      "name": "integration_id",
      "required": true,
      "schema": {
       "title": "Integration Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Test Integration",
    "tags": [
     "integrations"
    ]
   }
  },
  "/api/v1/internal/app/alerts": {
   "get": {
    "description": "The operator inbox rows THIS app raised (``source.name`` == the\napp id), newest first, with their acknowledgement state \u2014 so an app\ncan tell whether anyone has acted on what it said.",
    "operationId": "app_alerts_api_v1_internal_app_alerts_get",
    "parameters": [
     {
      "in": "query",
      "name": "unacked",
      "required": false,
      "schema": {
       "default": false,
       "title": "Unacked",
       "type": "boolean"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "maximum": 200,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "after_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "After Id"
      }
     },
     {
      "description": "Site key only: which app",
      "in": "query",
      "name": "app_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Site key only: which app",
       "title": "App Id"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "App Alerts",
    "tags": [
     "app-platform"
    ]
   }
  },
  "/api/v1/internal/app/cameras/{camera_id}/snapshot": {
   "get": {
    "description": "The camera's current frame as JPEG (via the KAI-C capture pool \u2014\nthe same path the zone editor's snapshot uses). 503 when no frame\ncan be captured.",
    "operationId": "app_camera_snapshot_api_v1_internal_app_cameras__camera_id__snapshot_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "App Camera Snapshot",
    "tags": [
     "app-platform"
    ]
   }
  },
  "/api/v1/internal/app/cameras/{camera_id}/stream": {
   "get": {
    "description": "An RTSP URL this app may read, for continuous frames.\n\nSnapshots answer \"what is there now\"; some apps must WATCH \u2014 a\ngesture, a sweep, a fall is a shape in time, and at one still every\nfew seconds it has already happened. Those apps need the stream.\n\nThe token minted here is scoped to THIS camera's path, not the\nwildcard the platform's own components carry. That is the whole\npoint of the route: apps sit on a shared network, so handing one a\nbare ``rtsp://mediamtx:8554/...`` would quietly grant it every\ncamera in the building and undo the per-app roster. A grant an app\ncannot widen is worth the extra endpoint.",
    "operationId": "app_camera_stream_api_v1_internal_app_cameras__camera_id__stream_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "App Camera Stream",
    "tags": [
     "app-platform"
    ]
   }
  },
  "/api/v1/internal/app/evidence": {
   "post": {
    "description": "Store one JPEG and return its path, for an app to cite in an alert.\n\nAn app that wants a photo on its alert cannot put the photo IN the\nalert: alerts travel over NATS, whose default payload ceiling is\n1 MB, and a couple of base64 crops exceed it \u2014 the broker drops the\npublish and the alert is simply never seen. So the picture comes\nhere first and only ``{\"path\": ...}`` rides along.\n\nContent-addressed by the store, so re-uploading the same bytes is\nfree and returns the same path.",
    "operationId": "app_evidence_upload_api_v1_internal_app_evidence_post",
    "parameters": [
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "App Evidence Upload",
    "tags": [
     "app-platform"
    ]
   }
  },
  "/api/v1/internal/app/plates/sessions": {
   "get": {
    "operationId": "app_plate_sessions_api_v1_internal_app_plates_sessions_get",
    "parameters": [
     {
      "in": "query",
      "name": "plate",
      "required": true,
      "schema": {
       "maxLength": 32,
       "minLength": 2,
       "title": "Plate",
       "type": "string"
      }
     },
     {
      "description": "Entry gates: comma-separated ids/handles",
      "in": "query",
      "name": "in_cameras",
      "required": false,
      "schema": {
       "default": "",
       "description": "Entry gates: comma-separated ids/handles",
       "title": "In Cameras",
       "type": "string"
      }
     },
     {
      "description": "Exit gates: comma-separated ids/handles",
      "in": "query",
      "name": "out_cameras",
      "required": false,
      "schema": {
       "default": "",
       "description": "Exit gates: comma-separated ids/handles",
       "title": "Out Cameras",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 50,
       "maximum": 200,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "App Plate Sessions",
    "tags": [
     "app-platform"
    ]
   }
  },
  "/api/v1/internal/app/plates/stats": {
   "get": {
    "operationId": "app_plate_stats_api_v1_internal_app_plates_stats_get",
    "parameters": [
     {
      "in": "query",
      "name": "days",
      "required": false,
      "schema": {
       "default": 7,
       "maximum": 90,
       "minimum": 1,
       "title": "Days",
       "type": "integer"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "App Plate Stats",
    "tags": [
     "app-platform"
    ]
   }
  },
  "/api/v1/internal/app/plates/summary": {
   "get": {
    "operationId": "app_plate_summary_api_v1_internal_app_plates_summary_get",
    "parameters": [
     {
      "in": "query",
      "name": "plate",
      "required": true,
      "schema": {
       "maxLength": 32,
       "minLength": 2,
       "title": "Plate",
       "type": "string"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "App Plate Summary",
    "tags": [
     "app-platform"
    ]
   }
  },
  "/api/v1/internal/app/recordings/{camera_id}": {
   "get": {
    "description": "Recorded segments for one camera (MediaMTX playback index).",
    "operationId": "app_recordings_list_api_v1_internal_app_recordings__camera_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "start",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "format": "date-time",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Start"
      }
     },
     {
      "in": "query",
      "name": "end",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "format": "date-time",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "End"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "App Recordings List",
    "tags": [
     "app-platform"
    ]
   }
  },
  "/api/v1/internal/app/recordings/{camera_id}/url": {
   "get": {
    "description": "A direct MediaMTX playback URL for one segment \u2014 the internal\nbase (apps run on the compose network), unlike the operator route,\nwhich hands the browser the external one.",
    "operationId": "app_recordings_url_api_v1_internal_app_recordings__camera_id__url_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "description": "Segment start, RFC3339",
      "in": "query",
      "name": "start",
      "required": true,
      "schema": {
       "description": "Segment start, RFC3339",
       "title": "Start",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "duration",
      "required": true,
      "schema": {
       "exclusiveMinimum": 0,
       "maximum": 86400,
       "title": "Duration",
       "type": "number"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "App Recordings Url",
    "tags": [
     "app-platform"
    ]
   }
  },
  "/api/v1/internal/app/state": {
   "get": {
    "operationId": "app_state_list_api_v1_internal_app_state_get",
    "parameters": [
     {
      "in": "query",
      "name": "prefix",
      "required": false,
      "schema": {
       "default": "",
       "maxLength": 200,
       "title": "Prefix",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "app_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "App Id"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "App State List",
    "tags": [
     "app-platform"
    ]
   }
  },
  "/api/v1/internal/app/state/{key}": {
   "delete": {
    "operationId": "app_state_delete_api_v1_internal_app_state__key__delete",
    "parameters": [
     {
      "in": "path",
      "name": "key",
      "required": true,
      "schema": {
       "title": "Key",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "app_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "App Id"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "App State Delete",
    "tags": [
     "app-platform"
    ]
   },
   "get": {
    "operationId": "app_state_get_api_v1_internal_app_state__key__get",
    "parameters": [
     {
      "in": "path",
      "name": "key",
      "required": true,
      "schema": {
       "title": "Key",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "app_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "App Id"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "App State Get",
    "tags": [
     "app-platform"
    ]
   },
   "put": {
    "description": "Set one key to any JSON value (last write wins). Keys \u2264 200\nchars, values \u2264 256 KB, \u2264 2000 keys per app \u2014 state, not storage.",
    "operationId": "app_state_put_api_v1_internal_app_state__key__put",
    "parameters": [
     {
      "in": "path",
      "name": "key",
      "required": true,
      "schema": {
       "title": "Key",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "app_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "App Id"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "title": "Value"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "App State Put",
    "tags": [
     "app-platform"
    ]
   }
  },
  "/api/v1/internal/camera-agent/cameras": {
   "get": {
    "description": "Return active cameras as frame sources for camera-agent.\n\n``X-Detect-Hwaccel`` is the caller's **resolved** decode backend \u2014 what it\ncan actually do, not what it was configured to want. When present it wins\nover ``settings.detect_hwaccel`` for the auto tap decision below.\n\nWhy: handing out the full-resolution main stream is a bet that the reader\nhas a GPU to absorb it. That bet used to be placed on a setting BOTH sides\nread independently, so a deployment with ``DETECT_HWACCEL=vaapi`` but no\n``/dev/dri`` passed through got the main stream *and* software decode \u2014\nseveral times the intended cost, silently. The reader is the only party\nthat knows whether the render node is really there, so it now says so and\nwe believe it. A caller that sends no header keeps the old behaviour.\n\nPrefer the MediaMTX internal RTSP tap so OpenNVR remains the owner of the\ncamera connection. If the deployment disables that tap, fall back to the\nstored camera RTSP URL.\n\nThe returned ``frame_url`` for MediaMTX tap paths includes a signed JWT\n(``?jwt=<token>``) so the camera-agent can authenticate with MediaMTX\nwithout needing the ``MEDIAMTX_SECRET`` key in its own config.",
    "operationId": "list_camera_agent_sources_api_v1_internal_camera_agent_cameras_get",
    "parameters": [
     {
      "in": "header",
      "name": "X-Detect-Hwaccel",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Detect-Hwaccel"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Camera Agent Sources Api V1 Internal Camera Agent Cameras Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List Camera Agent Sources",
    "tags": [
     "internal-camera-agent"
    ]
   }
  },
  "/api/v1/internal/camera-agent/detect-config": {
   "get": {
    "description": "Effective Tier-0 gate override for the detect-pipeline.\n\nThe pipeline polls this on its reconcile tick (guided promotion: an admin\nflips shadow->enforce in the UI; the pipeline applies it live, no\nredeploy). ``gate_mode: null`` means \"no override \u2014 follow your env\".",
    "operationId": "get_detect_config_api_v1_internal_camera_agent_detect_config_get",
    "parameters": [
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get Detect Config",
    "tags": [
     "internal-camera-agent"
    ]
   }
  },
  "/api/v1/internal/camera-agent/events": {
   "get": {
    "description": "Event-store read for trusted internal components (the camera agents).\n\nSame OVERLAP query the user API serves, fleet-wide: the agent is a\nplatform component like tier0, not a per-user browser session \u2014 its\nanswers are already scoped by which cameras it is configured to see.",
    "operationId": "internal_list_events_api_v1_internal_camera_agent_events_get",
    "parameters": [
     {
      "in": "query",
      "name": "camera_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Camera Id"
      }
     },
     {
      "in": "query",
      "name": "label",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Label"
      }
     },
     {
      "in": "query",
      "name": "plate",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Plate"
      }
     },
     {
      "in": "query",
      "name": "from",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "format": "date-time",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "From"
      }
     },
     {
      "in": "query",
      "name": "to",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "format": "date-time",
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "To"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 100,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Internal List Events",
    "tags": [
     "internal-camera-agent"
    ]
   },
   "post": {
    "description": "Canonical-store ingest (RFC-0001 C1): persist a visit + its evidence.\n\nCalled by the detect-pipeline when a track ends \u2014 the moment its best\nframe is final. Idempotent enough for retries: identical evidence\ncontent-addresses to the same file; duplicate rows are tolerated and\ncheap to de-dup at query time via (camera_id, track_id, started_at).",
    "operationId": "ingest_track_event_api_v1_internal_camera_agent_events_post",
    "parameters": [
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/TrackEventIn"
       }
      }
     },
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Ingest Track Event",
    "tags": [
     "internal-camera-agent"
    ]
   }
  },
  "/api/v1/internal/camera-agent/events/{event_id}/evidence": {
   "get": {
    "description": "The visit's best-frame JPEG, for agent-side face match / VLM looks.",
    "operationId": "internal_event_evidence_api_v1_internal_camera_agent_events__event_id__evidence_get",
    "parameters": [
     {
      "in": "path",
      "name": "event_id",
      "required": true,
      "schema": {
       "title": "Event Id",
       "type": "integer"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Internal Event Evidence",
    "tags": [
     "internal-camera-agent"
    ]
   }
  },
  "/api/v1/internal/camera-agent/events/{event_id}/scene-evidence": {
   "get": {
    "description": "The whole frame behind the best crop \u2014 a wider look for the VLM path.\n\n404 when the pipeline sent no scene frame (or the row predates the\ncolumn); callers fall back to ``/evidence``.",
    "operationId": "internal_event_scene_evidence_api_v1_internal_camera_agent_events__event_id__scene_evidence_get",
    "parameters": [
     {
      "in": "path",
      "name": "event_id",
      "required": true,
      "schema": {
       "title": "Event Id",
       "type": "integer"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Internal Event Scene Evidence",
    "tags": [
     "internal-camera-agent"
    ]
   }
  },
  "/api/v1/internal/camera-agent/plates/attempt": {
   "post": {
    "description": "Accept one early plate attempt (multi-frame OCR). The OCR runs\nin the background \u2014 this endpoint only validates and queues, so the\nTier-0 poster thread never waits on an inference.",
    "operationId": "ingest_plate_attempt_api_v1_internal_camera_agent_plates_attempt_post",
    "parameters": [
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PlateAttemptIn"
       }
      }
     },
     "required": true
    },
    "responses": {
     "202": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Ingest Plate Attempt",
    "tags": [
     "internal-camera-agent"
    ]
   }
  },
  "/api/v1/internal/camera-agent/recordings/frame": {
   "get": {
    "description": "One JPEG from recorded footage at a past instant, for the agent's\ndescribe_window. Reuses the recordings clip-resolution + ffmpeg extract;\ninternal-key authed like the other camera-agent endpoints.",
    "operationId": "internal_recording_frame_api_v1_internal_camera_agent_recordings_frame_get",
    "parameters": [
     {
      "description": "Camera ID",
      "in": "query",
      "name": "camera_id",
      "required": true,
      "schema": {
       "description": "Camera ID",
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "description": "Wall-clock instant (ISO 8601)",
      "in": "query",
      "name": "at",
      "required": true,
      "schema": {
       "description": "Wall-clock instant (ISO 8601)",
       "title": "At",
       "type": "string"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Internal Recording Frame",
    "tags": [
     "internal-camera-agent"
    ]
   }
  },
  "/api/v1/internal/camera-agent/skills": {
   "get": {
    "description": "RFC-0002 Phase 1: the skills-registry view, on the internal door.\n\nSame derivation (and same TTL-cached KAI-C probes) as the operator's\n``GET /api/v1/skills`` \u2014 this route exists because the camera agent\nis a service authenticating with ``X-Internal-Api-Key``, not a user\nwith a JWT. One view, two doors; the derivation stays in\n``services/skills_registry.py`` so they can never drift.",
    "operationId": "internal_skills_registry_api_v1_internal_camera_agent_skills_get",
    "parameters": [
     {
      "in": "header",
      "name": "X-Internal-Api-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     },
     {
      "in": "header",
      "name": "X-Internal-API-Key",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Internal-Api-Key"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Internal Skills Registry",
    "tags": [
     "internal-camera-agent"
    ]
   }
  },
  "/api/v1/media-source/settings": {
   "get": {
    "operationId": "get_media_source_settings_api_v1_media_source_settings_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Media Source Settings",
    "tags": [
     "media-source"
    ]
   },
   "put": {
    "operationId": "update_media_source_settings_api_v1_media_source_settings_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/MediaSourceSettingsUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Media Source Settings",
    "tags": [
     "media-source"
    ]
   }
  },
  "/api/v1/media-source/settings/upload": {
   "post": {
    "description": "Accept PEM files and persist their text content into media_source settings.\n\nThis enables uploading BYOK materials directly rather than pasting PEM text.",
    "operationId": "upload_media_source_settings_api_v1_media_source_settings_upload_post",
    "requestBody": {
     "content": {
      "multipart/form-data": {
       "schema": {
        "$ref": "#/components/schemas/Body_upload_media_source_settings_api_v1_media_source_settings_upload_post"
       }
      }
     }
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Upload Media Source Settings",
    "tags": [
     "media-source"
    ]
   }
  },
  "/api/v1/mediamtx/admin/global": {
   "get": {
    "operationId": "mtx_global_get_api_v1_mediamtx_admin_global_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Mtx Global Get",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   },
   "patch": {
    "operationId": "mtx_global_patch_api_v1_mediamtx_admin_global_patch",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Payload",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Mtx Global Patch",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/admin/pathdefaults": {
   "get": {
    "operationId": "mtx_pathdefaults_get_api_v1_mediamtx_admin_pathdefaults_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Mtx Pathdefaults Get",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   },
   "patch": {
    "operationId": "mtx_pathdefaults_patch_api_v1_mediamtx_admin_pathdefaults_patch",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Payload",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Mtx Pathdefaults Patch",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/admin/paths/list": {
   "get": {
    "description": "List all active paths/streams.",
    "operationId": "mtx_paths_list_api_v1_mediamtx_admin_paths_list_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Mtx Paths List",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/admin/paths/{camera_id}": {
   "get": {
    "description": "Get active path information for a camera.",
    "operationId": "mtx_paths_get_api_v1_mediamtx_admin_paths__camera_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Mtx Paths Get",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   },
   "patch": {
    "operationId": "mtx_paths_patch_api_v1_mediamtx_admin_paths__camera_id__patch",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Payload",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Mtx Paths Patch",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/admin/recordings/disable/{camera_id}": {
   "post": {
    "description": "Disable recording for a camera stream.",
    "operationId": "disable_recording_api_v1_mediamtx_admin_recordings_disable__camera_id__post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Disable Recording",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/admin/recordings/enable/{camera_id}": {
   "post": {
    "description": "Enable recording for a camera stream with configurable duration.\n\n`duration` is the segment length (`recordSegmentDuration`) \u2014 when a new\nrecording file is started. Defaults to the configured\nRECORDING_SEGMENT_SECONDS (single source of truth).\n\n`part_duration` is the fMP4 part length (`recordPartDuration`) \u2014 the\nflush/seek granularity *inside* each file. Defaults to `1s` to match the\nmediamtx*.yml configs and favour low-latency playback.",
    "operationId": "enable_recording_api_v1_mediamtx_admin_recordings_enable__camera_id__post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "duration",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Duration"
      }
     },
     {
      "in": "query",
      "name": "part_duration",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "default": "1s",
       "title": "Part Duration"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Enable Recording",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/admin/recordings/list": {
   "get": {
    "description": "List all recordings or for a specific camera.",
    "operationId": "mtx_recordings_list_api_v1_mediamtx_admin_recordings_list_get",
    "parameters": [
     {
      "in": "query",
      "name": "camera_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "title": "Camera Id"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Mtx Recordings List",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/admin/recordings/status/{camera_id}": {
   "get": {
    "description": "Get current recording status for a camera.",
    "operationId": "get_recording_status_api_v1_mediamtx_admin_recordings_status__camera_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Recording Status",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/admin/recordings/{camera_id}/{segment}": {
   "delete": {
    "description": "Delete a recording segment.",
    "operationId": "mtx_recording_delete_api_v1_mediamtx_admin_recordings__camera_id___segment__delete",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "segment",
      "required": true,
      "schema": {
       "title": "Segment",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Mtx Recording Delete",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   },
   "get": {
    "description": "Get recording segment information.",
    "operationId": "mtx_recording_get_api_v1_mediamtx_admin_recordings__camera_id___segment__get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "path",
      "name": "segment",
      "required": true,
      "schema": {
       "title": "Segment",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Mtx Recording Get",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/admin/streams/push/{camera_id}": {
   "post": {
    "description": "Push RTSP stream to MediaMTX.\n\nNVR policy: recording is mandatory, so ``enable_recording`` is forced on\nhere regardless of the query param \u2014 a `curl` cannot provision a camera\nwithout recording. Enforced at the HTTP entry point (not in the shared\nservice, which stays policy-neutral and DB-free for unit tests).",
    "operationId": "push_rtsp_stream_api_v1_mediamtx_admin_streams_push__camera_id__post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "rtsp_url",
      "required": true,
      "schema": {
       "title": "Rtsp Url",
       "type": "string"
      }
     },
     {
      "in": "query",
      "name": "enable_recording",
      "required": false,
      "schema": {
       "default": false,
       "title": "Enable Recording",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Push Rtsp Stream",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/health": {
   "get": {
    "description": "Lightweight health check for MediaMTX Admin API.\n\nReturns { status: \"ok\"|\"down\", admin_api?: str | None, http_status?: int }\n\nAUTHENTICATION, added after a coordinated disclosure (S9S Security\nResearch, 2026): this was the one endpoint in the router with no\ndependency at all, and no middleware covers it, so it answered\nanonymously \u2014 publishing ``mediamtx_admin_api``, the internal admin\nURL, and raw exception text to anyone who asked.\n\nIt stays open to any signed-in user rather than superusers because\nthe UI shows a health dot to everyone; the ADDRESS and the error\ndetail are the parts that are privileged, so those are returned only\nto a superuser. Everyone else gets the up/down they need.",
    "operationId": "mediamtx_health_api_v1_mediamtx_health_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Mediamtx Health",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/hooks/path-not-ready": {
   "get": {
    "operationId": "hook_path_not_ready_api_v1_mediamtx_hooks_path_not_ready_get",
    "parameters": [
     {
      "description": "MediaMTX path name (MTX_PATH)",
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "description": "MediaMTX path name (MTX_PATH)",
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Hook Path Not Ready",
    "tags": [
     "mediamtx",
     "hooks"
    ]
   }
  },
  "/api/v1/mediamtx/hooks/path-ready": {
   "get": {
    "operationId": "hook_path_ready_api_v1_mediamtx_hooks_path_ready_get",
    "parameters": [
     {
      "description": "MediaMTX path name (MTX_PATH)",
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "description": "MediaMTX path name (MTX_PATH)",
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Hook Path Ready",
    "tags": [
     "mediamtx",
     "hooks"
    ]
   }
  },
  "/api/v1/mediamtx/hooks/segment-complete": {
   "get": {
    "operationId": "hook_segment_complete_api_v1_mediamtx_hooks_segment_complete_get",
    "parameters": [
     {
      "description": "MediaMTX path name (MTX_PATH)",
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "description": "MediaMTX path name (MTX_PATH)",
       "title": "Path",
       "type": "string"
      }
     },
     {
      "description": "Segment file path (MTX_SEGMENT_PATH)",
      "in": "query",
      "name": "segment_path",
      "required": true,
      "schema": {
       "description": "Segment file path (MTX_SEGMENT_PATH)",
       "title": "Segment Path",
       "type": "string"
      }
     },
     {
      "description": "Segment duration (MTX_SEGMENT_DURATION)",
      "in": "query",
      "name": "segment_duration",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Segment duration (MTX_SEGMENT_DURATION)",
       "title": "Segment Duration"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Hook Segment Complete",
    "tags": [
     "mediamtx",
     "hooks"
    ]
   }
  },
  "/api/v1/mediamtx/hooks/segment-create": {
   "get": {
    "operationId": "hook_segment_create_api_v1_mediamtx_hooks_segment_create_get",
    "parameters": [
     {
      "description": "MediaMTX path name (MTX_PATH)",
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "description": "MediaMTX path name (MTX_PATH)",
       "title": "Path",
       "type": "string"
      }
     },
     {
      "description": "Segment file path (MTX_SEGMENT_PATH)",
      "in": "query",
      "name": "segment_path",
      "required": true,
      "schema": {
       "description": "Segment file path (MTX_SEGMENT_PATH)",
       "title": "Segment Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Hook Segment Create",
    "tags": [
     "mediamtx",
     "hooks"
    ]
   }
  },
  "/api/v1/mediamtx/setup": {
   "get": {
    "description": "Get MediaMTX setup instructions and configuration.",
    "operationId": "get_mediamtx_setup_api_v1_mediamtx_setup_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Mediamtx Setup",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/startup/hook": {
   "get": {
    "description": "MediaMTX startup hook endpoint.\nCalled by MediaMTX runOnInit hook when server starts.\nTriggers automatic re-provisioning of all cameras from database.",
    "operationId": "mediamtx_startup_hook_api_v1_mediamtx_startup_hook_get",
    "parameters": [
     {
      "description": "Delay in seconds before starting auto-provisioning",
      "in": "query",
      "name": "delay",
      "required": false,
      "schema": {
       "default": 5,
       "description": "Delay in seconds before starting auto-provisioning",
       "title": "Delay",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Mediamtx Startup Hook",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/startup/provision-all": {
   "post": {
    "description": "Manually trigger auto-provisioning of all cameras.",
    "operationId": "provision_all_cameras_api_v1_mediamtx_startup_provision_all_post",
    "parameters": [
     {
      "in": "query",
      "name": "delay_seconds",
      "required": false,
      "schema": {
       "default": 0,
       "title": "Delay Seconds",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "max_retries",
      "required": false,
      "schema": {
       "default": 3,
       "title": "Max Retries",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "retry_delay",
      "required": false,
      "schema": {
       "default": 2,
       "title": "Retry Delay",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Provision All Cameras",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/startup/provision-camera/{camera_id}": {
   "post": {
    "description": "Manually provision a specific camera.",
    "operationId": "provision_single_camera_api_v1_mediamtx_startup_provision_camera__camera_id__post",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "force",
      "required": false,
      "schema": {
       "default": false,
       "title": "Force",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Provision Single Camera",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/startup/push-path-defaults": {
   "post": {
    "description": "Manually push the recording path defaults to MediaMTX.\nThis is useful when recording path is changed via UI and you want to apply it\nwithout restarting MediaMTX or the application server.",
    "operationId": "push_path_defaults_api_v1_mediamtx_startup_push_path_defaults_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Push Path Defaults",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/mediamtx/startup/status": {
   "get": {
    "description": "Get status of all cameras and their provisioning state.",
    "operationId": "get_startup_status_api_v1_mediamtx_startup_status_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Startup Status",
    "tags": [
     "mediamtx",
     "control-api"
    ]
   }
  },
  "/api/v1/network/camera-lan": {
   "get": {
    "operationId": "get_camera_lan_api_v1_network_camera_lan_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Camera Lan",
    "tags": [
     "network"
    ]
   },
   "put": {
    "operationId": "update_camera_lan_api_v1_network_camera_lan_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/NetworkConfig"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Camera Lan",
    "tags": [
     "network"
    ]
   }
  },
  "/api/v1/network/camera-lan/isolate": {
   "post": {
    "description": "Create a high-priority firewall rule that denies outbound traffic from the camera LAN subnet.\n\nNote: This stores the rule in DB; applying it at OS level requires an external agent.",
    "operationId": "isolate_camera_lan_api_v1_network_camera_lan_isolate_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Isolate Camera Lan",
    "tags": [
     "network"
    ]
   }
  },
  "/api/v1/network/uplink": {
   "get": {
    "operationId": "get_uplink_api_v1_network_uplink_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Uplink",
    "tags": [
     "network"
    ]
   },
   "put": {
    "operationId": "update_uplink_api_v1_network_uplink_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/NetworkConfig"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Uplink",
    "tags": [
     "network"
    ]
   }
  },
  "/api/v1/occupancy/footfall": {
   "get": {
    "description": "Entries / exits through each camera's entry line and dwell inside\nits zone, hourly and in total, over the window.",
    "operationId": "get_occupancy_footfall_api_v1_occupancy_footfall_get",
    "parameters": [
     {
      "in": "query",
      "name": "hours",
      "required": false,
      "schema": {
       "default": 24,
       "title": "Hours",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Occupancy Footfall",
    "tags": [
     "occupancy"
    ]
   }
  },
  "/api/v1/occupancy/heatmap": {
   "get": {
    "description": "Where watched entities stood on one camera over the window \u2014\na unit-space grid the Occupancy page paints over a camera still.",
    "operationId": "get_occupancy_heatmap_api_v1_occupancy_heatmap_get",
    "parameters": [
     {
      "in": "query",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "hours",
      "required": false,
      "schema": {
       "default": 24,
       "title": "Hours",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Occupancy Heatmap",
    "tags": [
     "occupancy"
    ]
   }
  },
  "/api/v1/occupancy/history": {
   "get": {
    "description": "Occupancy trends for the charts: bucketed avg/max per camera over\nthe window, and busiest hours of day over the last 7 days.",
    "operationId": "get_occupancy_history_api_v1_occupancy_history_get",
    "parameters": [
     {
      "in": "query",
      "name": "hours",
      "required": false,
      "schema": {
       "default": 24,
       "title": "Hours",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Occupancy History",
    "tags": [
     "occupancy"
    ]
   }
  },
  "/api/v1/occupancy/report": {
   "get": {
    "description": "The period occupancy report (printable from the Occupancy page):\npeaks, averages, busiest hours, footfall and stays per camera.\n``tz_offset_minutes`` = the browser's offset east of UTC.",
    "operationId": "get_occupancy_report_api_v1_occupancy_report_get",
    "parameters": [
     {
      "in": "query",
      "name": "days",
      "required": false,
      "schema": {
       "default": 7,
       "title": "Days",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "tz_offset_minutes",
      "required": false,
      "schema": {
       "default": 0,
       "title": "Tz Offset Minutes",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Occupancy Report",
    "tags": [
     "occupancy"
    ]
   }
  },
  "/api/v1/password-policy/": {
   "get": {
    "operationId": "get_policy_api_v1_password_policy__get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PasswordPolicyResponse"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Policy",
    "tags": [
     "password-policy"
    ]
   },
   "put": {
    "operationId": "update_policy_api_v1_password_policy__put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PasswordPolicyUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PasswordPolicyResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Policy",
    "tags": [
     "password-policy"
    ]
   }
  },
  "/api/v1/permissions/": {
   "get": {
    "operationId": "list_permissions_api_v1_permissions__get",
    "parameters": [
     {
      "in": "query",
      "name": "skip",
      "required": false,
      "schema": {
       "default": 0,
       "title": "Skip",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 200,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PermissionList"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Permissions",
    "tags": [
     "permissions"
    ]
   },
   "post": {
    "operationId": "create_permission_api_v1_permissions__post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PermissionCreate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PermissionResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create Permission",
    "tags": [
     "permissions"
    ]
   }
  },
  "/api/v1/permissions/roles/{role_id}": {
   "get": {
    "operationId": "list_role_permissions_api_v1_permissions_roles__role_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "role_id",
      "required": true,
      "schema": {
       "title": "Role Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PermissionList"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Role Permissions",
    "tags": [
     "permissions"
    ]
   },
   "put": {
    "operationId": "set_role_permissions_api_v1_permissions_roles__role_id__put",
    "parameters": [
     {
      "in": "path",
      "name": "role_id",
      "required": true,
      "schema": {
       "title": "Role Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RolePermissionsSet"
       }
      }
     },
     "required": true
    },
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set Role Permissions",
    "tags": [
     "permissions"
    ]
   }
  },
  "/api/v1/permissions/{permission_id}": {
   "delete": {
    "operationId": "delete_permission_api_v1_permissions__permission_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "permission_id",
      "required": true,
      "schema": {
       "title": "Permission Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete Permission",
    "tags": [
     "permissions"
    ]
   },
   "put": {
    "operationId": "update_permission_api_v1_permissions__permission_id__put",
    "parameters": [
     {
      "in": "path",
      "name": "permission_id",
      "required": true,
      "schema": {
       "title": "Permission Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/PermissionUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/PermissionResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Permission",
    "tags": [
     "permissions"
    ]
   }
  },
  "/api/v1/recordings/cloud-upload/day": {
   "post": {
    "description": "Queue cloud upload for all DB recordings of a camera for a selected day.",
    "operationId": "queue_cloud_upload_for_day_api_v1_recordings_cloud_upload_day_post",
    "parameters": [
     {
      "description": "Camera ID",
      "in": "query",
      "name": "camera_id",
      "required": true,
      "schema": {
       "description": "Camera ID",
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "description": "Date in YYYY-MM-DD format",
      "in": "query",
      "name": "date",
      "required": true,
      "schema": {
       "description": "Date in YYYY-MM-DD format",
       "title": "Date",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Queue Cloud Upload For Day",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/cloud-upload/status": {
   "get": {
    "description": "Get current cloud upload worker and queue status.",
    "operationId": "get_cloud_upload_status_api_v1_recordings_cloud_upload_status_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Cloud Upload Status",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/config": {
   "get": {
    "description": "Get playback configuration for frontend.\nReturns the MediaMTX playback server URL and HLS settings.",
    "operationId": "get_playback_config_api_v1_recordings_config_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Playback Config",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/export": {
   "get": {
    "description": "Stream a recording clip to the browser as a file download.\n\nThe whole clip is STREAMED (chunked) from MediaMTX through the backend to\nthe browser's disk \u2014 never buffered in browser memory (the old client-side\nexport blob was multi-GB for long clips) and never fetched from an\nunauthenticated port.",
    "operationId": "export_clip_api_v1_recordings_export_get",
    "parameters": [
     {
      "description": "Export ticket",
      "in": "query",
      "name": "ticket",
      "required": true,
      "schema": {
       "description": "Export ticket",
       "title": "Ticket",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Export Clip",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/export/ticket": {
   "post": {
    "description": "Mint a short-lived, single-use ticket for a clip download.",
    "operationId": "create_export_ticket_api_v1_recordings_export_ticket_post",
    "parameters": [
     {
      "description": "Camera ID",
      "in": "query",
      "name": "camera_id",
      "required": true,
      "schema": {
       "description": "Camera ID",
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "description": "Clip start (RFC3339)",
      "in": "query",
      "name": "start",
      "required": true,
      "schema": {
       "description": "Clip start (RFC3339)",
       "title": "Start",
       "type": "string"
      }
     },
     {
      "description": "Clip length (s)",
      "in": "query",
      "name": "duration",
      "required": true,
      "schema": {
       "description": "Clip length (s)",
       "exclusiveMinimum": 0,
       "maximum": 14400,
       "title": "Duration",
       "type": "number"
      }
     },
     {
      "description": "Download filename",
      "in": "query",
      "name": "filename",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Download filename",
       "title": "Filename"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create Export Ticket",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/flag": {
   "put": {
    "description": "Flag (or unflag) every recording clip in a time range.\n\nFlagged clips are skipped by retention's age and disk-pressure sweeps\nwhile ``protect_flagged`` is enabled \u2014 this is what makes \"keep this\nincident's footage\" survive the retention window.",
    "operationId": "set_recording_flag_api_v1_recordings_flag_put",
    "parameters": [
     {
      "description": "Camera ID",
      "in": "query",
      "name": "camera_id",
      "required": true,
      "schema": {
       "description": "Camera ID",
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "description": "Range start (ISO 8601)",
      "in": "query",
      "name": "start",
      "required": true,
      "schema": {
       "description": "Range start (ISO 8601)",
       "title": "Start",
       "type": "string"
      }
     },
     {
      "description": "Range end (ISO 8601)",
      "in": "query",
      "name": "end",
      "required": true,
      "schema": {
       "description": "Range end (ISO 8601)",
       "title": "End",
       "type": "string"
      }
     },
     {
      "description": "Set or clear the protection flag",
      "in": "query",
      "name": "flagged",
      "required": true,
      "schema": {
       "description": "Set or clear the protection flag",
       "title": "Flagged",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Set Recording Flag",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/frame": {
   "get": {
    "description": "One JPEG frame from recorded footage at a past instant.\n\nPowers \"what was happening at 3:14pm\" \u2014 a caller (e.g. the camera agent's\ndescribe_window) samples a few of these across a window. Authenticated and\nowner-scoped like every recording route.",
    "operationId": "get_recording_frame_api_v1_recordings_frame_get",
    "parameters": [
     {
      "description": "Camera ID",
      "in": "query",
      "name": "camera_id",
      "required": true,
      "schema": {
       "description": "Camera ID",
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "description": "Wall-clock instant (ISO 8601) to extract a frame at",
      "in": "query",
      "name": "at",
      "required": true,
      "schema": {
       "description": "Wall-clock instant (ISO 8601) to extract a frame at",
       "title": "At",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get Recording Frame",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/list": {
   "get": {
    "description": "List recordings grouped by camera and LOCAL date (in ``tz``).\nReturns user-friendly recording counts (1 recording = 1 day per camera).\n\nServed from the recordings DB index (one aggregate query); cameras with\nno indexed rows fall back to MediaMTX, and the whole endpoint falls back\nto MediaMTX/filesystem when the index is disabled.",
    "operationId": "list_recordings_by_date_api_v1_recordings_list_get",
    "parameters": [
     {
      "description": "Filter by camera ID",
      "in": "query",
      "name": "camera_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "description": "Filter by camera ID",
       "title": "Camera Id"
      }
     },
     {
      "description": "IANA timezone for day grouping (default: server local)",
      "in": "query",
      "name": "tz",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "IANA timezone for day grouping (default: server local)",
       "title": "Tz"
      }
     },
     {
      "description": "List binned (deleted) cameras' recordings instead \u2014 the Deleted Cameras page.",
      "in": "query",
      "name": "deleted_only",
      "required": false,
      "schema": {
       "default": false,
       "description": "List binned (deleted) cameras' recordings instead \u2014 the Deleted Cameras page.",
       "title": "Deleted Only",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List Recordings By Date",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/orphans": {
   "get": {
    "description": "List quarantined recording trees (newest first).",
    "operationId": "list_orphans_api_v1_recordings_orphans_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Orphans",
    "tags": [
     "recordings",
     "orphans"
    ]
   }
  },
  "/api/v1/recordings/orphans/rescan": {
   "post": {
    "description": "Run the identity/ownerless scan now instead of waiting for the next\nreconciler pass. Returns how many trees were quarantined.",
    "operationId": "rescan_orphans_api_v1_recordings_orphans_rescan_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Rescan Orphans",
    "tags": [
     "recordings",
     "orphans"
    ]
   }
  },
  "/api/v1/recordings/orphans/{orphan_id}": {
   "delete": {
    "description": "Permanently delete a quarantined tree (explicit admin action \u2014 one of\nthe only two sanctioned deletion paths for orphaned footage).",
    "operationId": "delete_orphan_api_v1_recordings_orphans__orphan_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "orphan_id",
      "required": true,
      "schema": {
       "title": "Orphan Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete Orphan",
    "tags": [
     "recordings",
     "orphans"
    ]
   }
  },
  "/api/v1/recordings/orphans/{orphan_id}/attach": {
   "post": {
    "description": "Merge a quarantined tree into an existing camera's directory and\nreindex it. Never overwrites; a partial merge (name collisions) keeps\nthe remainder quarantined and reports the skipped files.",
    "operationId": "attach_orphan_api_v1_recordings_orphans__orphan_id__attach_post",
    "parameters": [
     {
      "in": "path",
      "name": "orphan_id",
      "required": true,
      "schema": {
       "title": "Orphan Id",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "additionalProperties": true,
        "title": "Payload",
        "type": "object"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Attach Orphan",
    "tags": [
     "recordings",
     "orphans"
    ]
   }
  },
  "/api/v1/recordings/playback/cameras": {
   "get": {
    "description": "List all cameras that have recordings.\nQueries MediaMTX for each camera.",
    "operationId": "list_recording_cameras_api_v1_recordings_playback_cameras_get",
    "parameters": [
     {
      "description": "List binned (deleted) cameras' recordings instead \u2014 the Deleted Cameras page.",
      "in": "query",
      "name": "deleted_only",
      "required": false,
      "schema": {
       "default": false,
       "description": "List binned (deleted) cameras' recordings instead \u2014 the Deleted Cameras page.",
       "title": "Deleted Only",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List Recording Cameras",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/playback/hls": {
   "get": {
    "description": "Create an HLS playback session for VOD-style recording playback.\n\nReturns a session with manifest URL that can be used with HLS.js.\nSessions are time-limited and automatically expire.\n\nSecurity:\n- Requires authentication (JWT token)\n- Enforces camera-level permissions\n- Session-based auth for subsequent requests",
    "operationId": "create_hls_session_api_v1_recordings_playback_hls_get",
    "parameters": [
     {
      "description": "Camera ID",
      "in": "query",
      "name": "camera_id",
      "required": true,
      "schema": {
       "description": "Camera ID",
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "description": "Start time in RFC3339 format",
      "in": "query",
      "name": "start",
      "required": true,
      "schema": {
       "description": "Start time in RFC3339 format",
       "title": "Start",
       "type": "string"
      }
     },
     {
      "description": "End time in RFC3339 format",
      "in": "query",
      "name": "end",
      "required": true,
      "schema": {
       "description": "End time in RFC3339 format",
       "title": "End",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Create Hls Session",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/playback/hls/{session_id}": {
   "delete": {
    "description": "Explicitly delete/invalidate an HLS session.\n\nCalled when user stops playback to free resources.",
    "operationId": "delete_hls_session_api_v1_recordings_playback_hls__session_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Delete Hls Session",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/playback/hls/{session_id}/browser.mp4": {
   "get": {
    "description": "Serve an H.265 recording as a browser-playable ``hvc1`` video-only MP4.\n\nThe MP4 is VIRTUAL: a small in-RAM index (built sub-second, headers-only\nscan) maps every output byte to the original recording, and each HTTP\nRange request is answered by streaming the mapped bytes straight from the\nsource file \u2014 no ffmpeg, no re-encode, no on-disk copy. H.264 recordings\nnever hit this route (they use the HLS byte-range path).",
    "operationId": "get_browser_playable_recording_api_v1_recordings_playback_hls__session_id__browser_mp4_get",
    "parameters": [
     {
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get Browser Playable Recording",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/playback/hls/{session_id}/index.m3u8": {
   "get": {
    "description": "Serve the HLS VOD manifest for a session.\n\nSecurity: Session ID acts as authentication token.",
    "operationId": "get_hls_manifest_api_v1_recordings_playback_hls__session_id__index_m3u8_get",
    "parameters": [
     {
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get Hls Manifest",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/playback/hls/{session_id}/init.mp4": {
   "get": {
    "description": "Serve the fMP4 initialization segment.\n\nContains codec info needed to start playback.",
    "operationId": "get_hls_init_segment_api_v1_recordings_playback_hls__session_id__init_mp4_get",
    "parameters": [
     {
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get Hls Init Segment",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/playback/hls/{session_id}/media": {
   "get": {
    "description": "Serve byte ranges of the session's FIRST on-disk clip file (legacy path).\n\nKept for older manifests; new multi-file manifests address clips as\n``media/{n}`` (see get_hls_media_file).\n\nSecurity: session_id acts as the auth token (same as the other playback\nroutes). The file was resolved under the recordings base at session\ncreation (V-005), so no request-supplied path reaches the filesystem here.",
    "operationId": "get_hls_media_api_v1_recordings_playback_hls__session_id__media_get",
    "parameters": [
     {
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get Hls Media",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/playback/hls/{session_id}/media/{file_index}": {
   "get": {
    "description": "Serve byte ranges of one clip file in the session's playback window.\n\nThe multi-file byte-range manifest addresses each contiguous clip as\n``media/{n}``; hls.js fetches init segments and media segments as HTTP\nRanges against it, so playback crosses clip boundaries with zero session\nchurn and every seek is a single ranged read.\n\nSecurity: session_id is the auth token; the file list was resolved under\nthe recordings base at session creation (V-005) \u2014 ``file_index`` selects\nfrom that frozen list, no request-supplied path reaches the filesystem.",
    "operationId": "get_hls_media_file_api_v1_recordings_playback_hls__session_id__media__file_index__get",
    "parameters": [
     {
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     },
     {
      "in": "path",
      "name": "file_index",
      "required": true,
      "schema": {
       "title": "File Index",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get Hls Media File",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/playback/hls/{session_id}/segment-{segment_index}.m4s": {
   "get": {
    "description": "Serve an HLS media segment.\n\nProxies segment data from MediaMTX /get endpoint.\nUses streaming response for efficient delivery.",
    "operationId": "get_hls_segment_api_v1_recordings_playback_hls__session_id__segment__segment_index__m4s_get",
    "parameters": [
     {
      "in": "path",
      "name": "session_id",
      "required": true,
      "schema": {
       "title": "Session Id",
       "type": "string"
      }
     },
     {
      "in": "path",
      "name": "segment_index",
      "required": true,
      "schema": {
       "title": "Segment Index",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get Hls Segment",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/playback/list": {
   "get": {
    "description": "List available recordings from MediaMTX playback server.\nReturns segments with direct playback URLs.",
    "operationId": "list_recordings_api_v1_recordings_playback_list_get",
    "parameters": [
     {
      "description": "Camera path (e.g., cam-57)",
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "description": "Camera path (e.g., cam-57)",
       "title": "Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "List Recordings",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/playback/url": {
   "get": {
    "description": "Get a direct MediaMTX playback URL for a recording.\nThe URL can be used directly in a video player.",
    "operationId": "get_playback_url_api_v1_recordings_playback_url_get",
    "parameters": [
     {
      "description": "Camera path (e.g., cam-57)",
      "in": "query",
      "name": "path",
      "required": true,
      "schema": {
       "description": "Camera path (e.g., cam-57)",
       "title": "Path",
       "type": "string"
      }
     },
     {
      "description": "Start time in RFC3339 format",
      "in": "query",
      "name": "start",
      "required": true,
      "schema": {
       "description": "Start time in RFC3339 format",
       "title": "Start",
       "type": "string"
      }
     },
     {
      "description": "Duration in seconds",
      "in": "query",
      "name": "duration",
      "required": true,
      "schema": {
       "description": "Duration in seconds",
       "title": "Duration",
       "type": "number"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get Playback Url",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/retention": {
   "get": {
    "description": "Get recording retention settings.",
    "operationId": "get_retention_api_v1_recordings_retention_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Retention",
    "tags": [
     "recordings"
    ]
   },
   "put": {
    "description": "Update recording retention settings.",
    "operationId": "update_retention_api_v1_recordings_retention_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RecordingRetentionSettings"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Retention",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/schedule": {
   "get": {
    "description": "Get recording schedule settings.",
    "operationId": "get_schedule_api_v1_recordings_schedule_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Schedule",
    "tags": [
     "recordings"
    ]
   },
   "put": {
    "description": "Update recording schedule settings.",
    "operationId": "update_schedule_api_v1_recordings_schedule_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RecordingScheduleSettings"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Schedule",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/segments/{camera_id}": {
   "get": {
    "description": "Get the continuous recording segments for a camera on a given day.\n\nUnlike ``/list`` (which aggregates a whole day into one entry), this returns\nevery continuous recording run as its own segment with an absolute\n``start``, ``duration`` and a browser-reachable ``playback_url``. The DVR\nplayback timeline uses this to draw footage/gap blocks and to seek to any\nwall-clock instant via ``playback_base_url``/``path``.\n\nThe day window is LOCAL midnight \u2192 next local midnight (in ``tz``), or the\nexplicit ``start``/``end`` instants when provided. Served from the\nrecordings DB index; falls back to MediaMTX for unindexed cameras.",
    "operationId": "get_day_segments_api_v1_recordings_segments__camera_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "description": "Day in YYYY-MM-DD (interpreted in `tz`). Defaults to today.",
      "in": "query",
      "name": "date",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Day in YYYY-MM-DD (interpreted in `tz`). Defaults to today.",
       "title": "Date"
      }
     },
     {
      "description": "Explicit range start (ISO 8601), overrides date",
      "in": "query",
      "name": "start",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Explicit range start (ISO 8601), overrides date",
       "title": "Start"
      }
     },
     {
      "description": "Explicit range end (ISO 8601), overrides date",
      "in": "query",
      "name": "end",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "Explicit range end (ISO 8601), overrides date",
       "title": "End"
      }
     },
     {
      "description": "IANA timezone for interpreting `date` (default: server local)",
      "in": "query",
      "name": "tz",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "IANA timezone for interpreting `date` (default: server local)",
       "title": "Tz"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get Day Segments",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/sessions-for-ai": {
   "get": {
    "description": "Get recording sessions grouped by camera and date, specifically for AI processing.\nSessions are continuous recording periods (with small gaps allowed).\nFalls back to filesystem listing if MediaMTX is unavailable.",
    "operationId": "get_recording_sessions_for_ai_api_v1_recordings_sessions_for_ai_get",
    "parameters": [
     {
      "description": "Filter by camera ID",
      "in": "query",
      "name": "camera_id",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "description": "Filter by camera ID",
       "title": "Camera Id"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Get Recording Sessions For Ai",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/stats": {
   "get": {
    "description": "Get recording statistics for dashboard.\nReturns counts and durations in user-friendly format.\nFalls back to filesystem listing if MediaMTX is unavailable.",
    "operationId": "get_recording_stats_api_v1_recordings_stats_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Get Recording Stats",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/status/{camera_id}": {
   "get": {
    "description": "Get recording status for a camera.",
    "operationId": "recording_status_api_v1_recordings_status__camera_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Recording Status",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/recordings/storage": {
   "get": {
    "description": "Get recording storage settings.",
    "operationId": "get_storage_api_v1_recordings_storage_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Storage",
    "tags": [
     "recordings"
    ]
   },
   "put": {
    "description": "Update recording storage settings and sync to MediaMTX.",
    "operationId": "update_storage_api_v1_recordings_storage_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RecordingStorageSettings"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Storage",
    "tags": [
     "recordings"
    ]
   }
  },
  "/api/v1/roles/": {
   "get": {
    "description": "Return a paginated list of roles (superuser only).",
    "operationId": "list_roles_api_v1_roles__get",
    "parameters": [
     {
      "in": "query",
      "name": "skip",
      "required": false,
      "schema": {
       "default": 0,
       "title": "Skip",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 100,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/RoleList"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Roles",
    "tags": [
     "roles"
    ]
   },
   "post": {
    "description": "Create a new role (superuser only).",
    "operationId": "create_role_api_v1_roles__post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RoleCreate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/RoleResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create Role",
    "tags": [
     "roles"
    ]
   }
  },
  "/api/v1/roles/{role_id}": {
   "delete": {
    "description": "Delete a role (superuser only). Prevent deletion if assigned to any user.",
    "operationId": "delete_role_api_v1_roles__role_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "role_id",
      "required": true,
      "schema": {
       "title": "Role Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete Role",
    "tags": [
     "roles"
    ]
   },
   "get": {
    "description": "Return a single role by ID (superuser only).",
    "operationId": "get_role_api_v1_roles__role_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "role_id",
      "required": true,
      "schema": {
       "title": "Role Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/RoleResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Role",
    "tags": [
     "roles"
    ]
   },
   "put": {
    "description": "Update an existing role (superuser only).",
    "operationId": "update_role_api_v1_roles__role_id__put",
    "parameters": [
     {
      "in": "path",
      "name": "role_id",
      "required": true,
      "schema": {
       "title": "Role Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/RoleUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/RoleResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Role",
    "tags": [
     "roles"
    ]
   }
  },
  "/api/v1/security/firewall/rules": {
   "get": {
    "operationId": "list_firewall_rules_api_v1_security_firewall_rules_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/FirewallRuleList"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Firewall Rules",
    "tags": [
     "security"
    ]
   },
   "post": {
    "operationId": "create_firewall_rule_api_v1_security_firewall_rules_post",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/FirewallRuleCreate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "201": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/FirewallRuleResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create Firewall Rule",
    "tags": [
     "security"
    ]
   }
  },
  "/api/v1/security/firewall/rules/{rule_id}": {
   "delete": {
    "operationId": "delete_firewall_rule_api_v1_security_firewall_rules__rule_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "rule_id",
      "required": true,
      "schema": {
       "title": "Rule Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "204": {
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete Firewall Rule",
    "tags": [
     "security"
    ]
   },
   "put": {
    "operationId": "update_firewall_rule_api_v1_security_firewall_rules__rule_id__put",
    "parameters": [
     {
      "in": "path",
      "name": "rule_id",
      "required": true,
      "schema": {
       "title": "Rule Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/FirewallRuleUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/FirewallRuleResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Firewall Rule",
    "tags": [
     "security"
    ]
   }
  },
  "/api/v1/security/settings/{key}": {
   "get": {
    "operationId": "get_security_setting_api_v1_security_settings__key__get",
    "parameters": [
     {
      "in": "path",
      "name": "key",
      "required": true,
      "schema": {
       "title": "Key",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/SecuritySettingResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Security Setting",
    "tags": [
     "security"
    ]
   },
   "put": {
    "operationId": "set_security_setting_api_v1_security_settings__key__put",
    "parameters": [
     {
      "in": "path",
      "name": "key",
      "required": true,
      "schema": {
       "title": "Key",
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SecuritySettingPayload"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/SecuritySettingResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Set Security Setting",
    "tags": [
     "security"
    ]
   }
  },
  "/api/v1/skills": {
   "get": {
    "description": "Every skill the platform knows, with live status \u2014 RFC-0002\ndecision 2's view over the four sources. Consumers: the camera\nagent's skills panel, the App Catalog, and anything else that today\nreinvents this derivation privately.",
    "operationId": "list_skills_api_v1_skills_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response List Skills Api V1 Skills Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List Skills",
    "tags": [
     "skills"
    ]
   }
  },
  "/api/v1/skills/{skill_id}/cameras": {
   "get": {
    "operationId": "get_skill_cameras_api_v1_skills__skill_id__cameras_get",
    "parameters": [
     {
      "in": "path",
      "name": "skill_id",
      "required": true,
      "schema": {
       "title": "Skill Id",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Get Skill Cameras Api V1 Skills  Skill Id  Cameras Get",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Skill Cameras",
    "tags": [
     "skills"
    ]
   }
  },
  "/api/v1/skills/{skill_id}/cameras/{camera_id}": {
   "delete": {
    "description": "Release one consumer's claim. The union shrinks by exactly this\nclaim; other consumers' assignments survive (decision 8).",
    "operationId": "release_skill_camera_api_v1_skills__skill_id__cameras__camera_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "skill_id",
      "required": true,
      "schema": {
       "title": "Skill Id",
       "type": "string"
      }
     },
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "consumer",
      "required": true,
      "schema": {
       "title": "Consumer",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Release Skill Camera Api V1 Skills  Skill Id  Cameras  Camera Id  Delete",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Release Skill Camera",
    "tags": [
     "skills"
    ]
   },
   "put": {
    "description": "Declare one consumer's claim (desired state; idempotent upsert).\n\nThe vocabulary stays open \u2014 an assignment may name a skill whose\ncapability isn't installed yet (annotate-never-gate, the\nper-camera-assignment design rule); GET /skills is where its status\nshows as missing-dependency.",
    "operationId": "declare_skill_camera_api_v1_skills__skill_id__cameras__camera_id__put",
    "parameters": [
     {
      "in": "path",
      "name": "skill_id",
      "required": true,
      "schema": {
       "title": "Skill Id",
       "type": "string"
      }
     },
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/Body_declare_skill_camera_api_v1_skills__skill_id__cameras__camera_id__put"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "additionalProperties": true,
         "title": "Response Declare Skill Camera Api V1 Skills  Skill Id  Cameras  Camera Id  Put",
         "type": "object"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Declare Skill Camera",
    "tags": [
     "skills"
    ]
   }
  },
  "/api/v1/streams/hls/{camera_id}": {
   "get": {
    "description": "Return HLS URL and JWT token for the specified camera.\n\nSecurity:\n- JWT token required for MediaMTX access\n- Token scoped to this camera only",
    "operationId": "get_hls_url_api_v1_streams_hls__camera_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Hls Url",
    "tags": [
     "streams"
    ]
   }
  },
  "/api/v1/streams/playback-token/{camera_id}": {
   "get": {
    "description": "Get a JWT token for accessing camera recordings/playback.\n\nSecurity:\n- Includes playback permission\n- Shorter expiry than live streams",
    "operationId": "get_playback_token_api_v1_streams_playback_token__camera_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "expiry_minutes",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "default": 30,
       "title": "Expiry Minutes"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Playback Token",
    "tags": [
     "streams"
    ]
   }
  },
  "/api/v1/streams/token/{camera_id}": {
   "get": {
    "description": "Get a JWT token for accessing a camera stream.\n\nThis token must be included in the Authorization header when\naccessing MediaMTX endpoints (WebRTC, HLS, RTSP, Playback).\n\nSecurity:\n- Token is scoped to specific camera\n- Short-lived (default 60 minutes)\n- Includes user identity for audit",
    "operationId": "get_stream_token_api_v1_streams_token__camera_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "expiry_minutes",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "integer"
        },
        {
         "type": "null"
        }
       ],
       "default": 60,
       "title": "Expiry Minutes"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Stream Token",
    "tags": [
     "streams"
    ]
   }
  },
  "/api/v1/streams/webrtc/{camera_id}": {
   "get": {
    "description": "Return WebRTC WHEP URL and JWT token for the specified camera.\n\nSecurity:\n- JWT token required for MediaMTX access\n- Token scoped to this camera only\n- 60-minute expiry\n\nNote: MediaMTX is bound to localhost. Frontend must proxy through backend\nor use the token with a backend WebRTC proxy endpoint.",
    "operationId": "get_whep_url_api_v1_streams_webrtc__camera_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Whep Url",
    "tags": [
     "streams"
    ]
   }
  },
  "/api/v1/streams/{camera_id}/info": {
   "get": {
    "description": "Get comprehensive stream information and JWT token for a camera.\n\nReturns all stream URLs and a single token valid for all protocols.",
    "operationId": "get_stream_info_api_v1_streams__camera_id__info_get",
    "parameters": [
     {
      "in": "path",
      "name": "camera_id",
      "required": true,
      "schema": {
       "title": "Camera Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Stream Info",
    "tags": [
     "streams"
    ]
   }
  },
  "/api/v1/suricata/alerts/stream": {
   "get": {
    "description": "Streams Suricata alerts from WSL to the frontend.",
    "operationId": "get_suricata_alerts_stream_api_v1_suricata_alerts_stream_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Suricata Alerts Stream"
   }
  },
  "/api/v1/suricata/logs": {
   "get": {
    "description": "Backward-compatible raw eve.json NDJSON response used by early UI.",
    "operationId": "get_suricata_logs_raw_api_v1_suricata_logs_get",
    "responses": {
     "200": {
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Suricata Logs Raw",
    "tags": [
     "suricata"
    ]
   }
  },
  "/api/v1/suricata/logs/eve": {
   "get": {
    "operationId": "get_suricata_eve_logs_api_v1_suricata_logs_eve_get",
    "parameters": [
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 200,
       "maximum": 5000,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "skip",
      "required": false,
      "schema": {
       "default": 0,
       "minimum": 0,
       "title": "Skip",
       "type": "integer"
      }
     },
     {
      "description": "Return only entries with 'event_type=alert'",
      "in": "query",
      "name": "only_alerts",
      "required": false,
      "schema": {
       "default": false,
       "description": "Return only entries with 'event_type=alert'",
       "title": "Only Alerts",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Suricata Eve Logs",
    "tags": [
     "suricata"
    ]
   }
  },
  "/api/v1/suricata/logs/fast": {
   "get": {
    "operationId": "get_suricata_fast_logs_api_v1_suricata_logs_fast_get",
    "parameters": [
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 200,
       "maximum": 5000,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "skip",
      "required": false,
      "schema": {
       "default": 0,
       "minimum": 0,
       "title": "Skip",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Suricata Fast Logs",
    "tags": [
     "suricata"
    ]
   }
  },
  "/api/v1/suricata/stats": {
   "get": {
    "description": "Aggregate Suricata eve.json into dashboard-friendly stats.\nDefault scans last N lines for performance, optionally filters by time window.",
    "operationId": "get_suricata_stats_api_v1_suricata_stats_get",
    "parameters": [
     {
      "description": "ISO start timestamp to filter events",
      "in": "query",
      "name": "start",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "ISO start timestamp to filter events",
       "title": "Start"
      }
     },
     {
      "description": "ISO end timestamp to filter events",
      "in": "query",
      "name": "end",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "description": "ISO end timestamp to filter events",
       "title": "End"
      }
     },
     {
      "description": "Max lines to scan from end of eve.json",
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 10000,
       "description": "Max lines to scan from end of eve.json",
       "maximum": 200000,
       "minimum": 10,
       "title": "Limit",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Suricata Stats",
    "tags": [
     "suricata"
    ]
   }
  },
  "/api/v1/system/events": {
   "get": {
    "description": "System alert history, newest first. With ``include_camera_alerts``\n(default), recent ``recording_stalled`` camera events are merged in (with\ncamera id/name) so the Alerts view gets both from one call.",
    "operationId": "list_system_events_api_v1_system_events_get",
    "parameters": [
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 200,
       "maximum": 1000,
       "minimum": 1,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "event_type",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "maxLength": 50,
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "Event Type"
      }
     },
     {
      "in": "query",
      "name": "include_camera_alerts",
      "required": false,
      "schema": {
       "default": true,
       "title": "Include Camera Alerts",
       "type": "boolean"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "List System Events",
    "tags": [
     "system"
    ]
   }
  },
  "/api/v1/system/monitoring-settings": {
   "get": {
    "description": "Get host monitoring thresholds.",
    "operationId": "get_monitoring_settings_api_v1_system_monitoring_settings_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Monitoring Settings",
    "tags": [
     "system"
    ]
   },
   "put": {
    "description": "Update host monitoring thresholds.",
    "operationId": "update_monitoring_settings_api_v1_system_monitoring_settings_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/SystemMonitoringSettings"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Monitoring Settings",
    "tags": [
     "system"
    ]
   }
  },
  "/api/v1/system/posture": {
   "get": {
    "description": "Expose the active offline-first policy so the UI can show a\ndeployment-mode badge and the operator can confirm the sovereignty profile.\nSee V-009 / V-022.\n\nRead-only and authenticated-user-scope (not just superuser) \u2014 operators\nmonitoring the system should be able to see this without admin rights.\nMirrors the boot-time audit entry written by core.policy.audit_boot_posture.",
    "operationId": "get_security_posture_api_v1_system_posture_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Security Posture",
    "tags": [
     "system"
    ]
   }
  },
  "/api/v1/system/reboot": {
   "post": {
    "operationId": "reboot_api_v1_system_reboot_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Reboot",
    "tags": [
     "system"
    ]
   }
  },
  "/api/v1/system/resources": {
   "get": {
    "description": "Latest host resource sample (CPU / memory / recordings-volume disk)\nplus active alerts and the effective thresholds. Active-user scope: this\npowers the dashboard health card, same rationale as /posture.",
    "operationId": "get_system_resources_api_v1_system_resources_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get System Resources",
    "tags": [
     "system"
    ]
   }
  },
  "/api/v1/system/resources/history": {
   "get": {
    "description": "Recent resource samples from the in-memory ring buffers (15s grain up\nto 1h, 5-min averages up to 24h). History does not survive restarts \u2014\npersistent history would mean constant writes on the monitored volume.",
    "operationId": "get_system_resources_history_api_v1_system_resources_history_get",
    "parameters": [
     {
      "in": "query",
      "name": "minutes",
      "required": false,
      "schema": {
       "default": 60,
       "maximum": 1440,
       "minimum": 1,
       "title": "Minutes",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get System Resources History",
    "tags": [
     "system"
    ]
   }
  },
  "/api/v1/system/shutdown": {
   "post": {
    "operationId": "shutdown_api_v1_system_shutdown_post",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Shutdown",
    "tags": [
     "system"
    ]
   }
  },
  "/api/v1/users/": {
   "get": {
    "description": "Get list of users (superuser only). Optionally filter by username/email with q parameter.",
    "operationId": "get_users_api_v1_users__get",
    "parameters": [
     {
      "in": "query",
      "name": "skip",
      "required": false,
      "schema": {
       "default": 0,
       "title": "Skip",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "limit",
      "required": false,
      "schema": {
       "default": 100,
       "title": "Limit",
       "type": "integer"
      }
     },
     {
      "in": "query",
      "name": "active_only",
      "required": false,
      "schema": {
       "default": true,
       "title": "Active Only",
       "type": "boolean"
      }
     },
     {
      "in": "query",
      "name": "q",
      "required": false,
      "schema": {
       "title": "Q",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/UserList"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Users",
    "tags": [
     "users"
    ]
   },
   "post": {
    "description": "Create a new user (superuser only).\n\n``is_superuser: true`` creates another superuser \u2014 the API's most\nprivileged write (every permission, every camera), so it takes the\ncaller's current TOTP code in ``X-MFA-Code`` like delete does.",
    "operationId": "create_user_api_v1_users__post",
    "parameters": [
     {
      "in": "header",
      "name": "X-MFA-Code",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Mfa-Code"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/UserCreate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/UserResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Create User",
    "tags": [
     "users"
    ]
   }
  },
  "/api/v1/users/me": {
   "get": {
    "description": "Get current user information.",
    "operationId": "get_current_user_info_api_v1_users_me_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/UserResponse"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Current User Info",
    "tags": [
     "users"
    ]
   },
   "put": {
    "description": "Update current user information (profile fields only).",
    "operationId": "update_current_user_api_v1_users_me_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/UserUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/UserResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Current User",
    "tags": [
     "users"
    ]
   }
  },
  "/api/v1/users/me/permissions": {
   "get": {
    "description": "Get current user's permissions based on their role.",
    "operationId": "get_current_user_permissions_api_v1_users_me_permissions_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Current User Permissions",
    "tags": [
     "users"
    ]
   }
  },
  "/api/v1/users/{user_id}": {
   "delete": {
    "description": "Delete a user (soft delete, superuser only).\n\nRequires the caller's current TOTP code in the X-MFA-Code header, and a\nuser can never delete their own account \u2014 a soft-deleted user cannot log\nin, so self-deletion bricks single-admin deployments (issue #176).",
    "operationId": "delete_user_api_v1_users__user_id__delete",
    "parameters": [
     {
      "in": "path",
      "name": "user_id",
      "required": true,
      "schema": {
       "title": "User Id",
       "type": "integer"
      }
     },
     {
      "in": "header",
      "name": "X-MFA-Code",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Mfa-Code"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Delete User",
    "tags": [
     "users"
    ]
   },
   "get": {
    "description": "Get user by ID (superuser only).",
    "operationId": "get_user_api_v1_users__user_id__get",
    "parameters": [
     {
      "in": "path",
      "name": "user_id",
      "required": true,
      "schema": {
       "title": "User Id",
       "type": "integer"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/UserResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get User",
    "tags": [
     "users"
    ]
   },
   "put": {
    "description": "Update user information (superuser only).\n\nChanging ``is_superuser`` (promote or demote) requires the caller's\ncurrent TOTP code in ``X-MFA-Code``; you cannot demote yourself, and\nthe last active superuser cannot be demoted or deactivated.",
    "operationId": "update_user_api_v1_users__user_id__put",
    "parameters": [
     {
      "in": "path",
      "name": "user_id",
      "required": true,
      "schema": {
       "title": "User Id",
       "type": "integer"
      }
     },
     {
      "in": "header",
      "name": "X-MFA-Code",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Mfa-Code"
      }
     }
    ],
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/UserUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/UserResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update User",
    "tags": [
     "users"
    ]
   }
  },
  "/api/v1/users/{user_id}/activate": {
   "post": {
    "description": "Reactivate a soft-deleted user (superuser only).\n\nUndoes a delete: the account can log in again. Requires the caller's\ncurrent TOTP code in the X-MFA-Code header, same as deletion.",
    "operationId": "activate_user_api_v1_users__user_id__activate_post",
    "parameters": [
     {
      "in": "path",
      "name": "user_id",
      "required": true,
      "schema": {
       "title": "User Id",
       "type": "integer"
      }
     },
     {
      "in": "header",
      "name": "X-MFA-Code",
      "required": false,
      "schema": {
       "anyOf": [
        {
         "type": "string"
        },
        {
         "type": "null"
        }
       ],
       "title": "X-Mfa-Code"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/UserResponse"
        }
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Activate User",
    "tags": [
     "users"
    ]
   }
  },
  "/api/v1/webrtc/rtc-config": {
   "get": {
    "description": "ICE configuration for RTCPeerConnection, used by the live player.\n\nAny authenticated user needs this to watch a stream, so it is not\nsuperuser-gated. TURN credentials are inherently client-side \u2014 the browser\ncannot relay through TURN without them \u2014 so restricting this endpoint would\nbreak playback rather than protect the secret. Keep TURN credentials\nshort-lived if that matters for a deployment.",
    "operationId": "get_client_rtc_config_api_v1_webrtc_rtc_config_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/WebRTCClientConfig"
        }
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Client Rtc Config",
    "tags": [
     "webrtc"
    ]
   }
  },
  "/api/v1/webrtc/settings": {
   "get": {
    "operationId": "get_webrtc_settings_api_v1_webrtc_settings_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Get Webrtc Settings",
    "tags": [
     "webrtc"
    ]
   },
   "put": {
    "operationId": "update_webrtc_settings_api_v1_webrtc_settings_put",
    "requestBody": {
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/WebRTCSettingsUpdate"
       }
      }
     },
     "required": true
    },
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "security": [
     {
      "HTTPBearer": []
     }
    ],
    "summary": "Update Webrtc Settings",
    "tags": [
     "webrtc"
    ]
   }
  },
  "/health": {
   "get": {
    "description": "Health check endpoint.",
    "operationId": "health_check_health_get",
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     }
    },
    "summary": "Health Check"
   }
  },
  "/{file_path}": {
   "get": {
    "operationId": "serve_static_or_spa__file_path__get",
    "parameters": [
     {
      "in": "path",
      "name": "file_path",
      "required": true,
      "schema": {
       "title": "File Path",
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "content": {
       "application/json": {
        "schema": {}
       }
      },
      "description": "Successful Response"
     },
     "422": {
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/HTTPValidationError"
        }
       }
      },
      "description": "Validation Error"
     }
    },
    "summary": "Serve Static Or Spa"
   }
  }
 }
}