{"openapi":"3.1.0","info":{"title":"Blue Lobster Instance API","description":"\n\n## INTRODUCTION\n\n- Create, restart and delete virtual machines using the /instances family of endpoints\n- Backup and restore instances using the backup endpoints\n- Monitor real-time instance statistics (CPU, memory, disk, network)\n- Access instance console via VNC proxy\n- Query the status of a task using the /tasks status endpoint\n\n## AUTHENTICATION AND BILLING\n\n- All endpoints require a key via the `X-API-Key` header\n- For access to this API please contact support@bluelobster.ai\n- Your account balance must be in good standing\n- Failure to pay will result in instance termination and data deletion.\n- API users agree to the terms of service, privacy policy, and acceptable use policy on Bluelobster.ai\n\n## LEGAL DISCLAIMERS\n\n- This API is in BETA status and is provided \"AS IS\" without any warranties of any kind\n- Blue Lobster reserves the right to modify, suspend, or discontinue any aspect of the API at any time without notice\n- Users acknowledge and accept all risks associated with using beta software, including:\n  - Potential system instability\n  - Data loss or corruption\n  - Service interruptions\n  - API changes that may break existing integrations\n- Users are solely responsible for:\n  - Backing up their data\n  - Testing API changes before production use\n  - Any losses or damages resulting from API usage\n- Service levels and uptime guarantees do not apply during our beta period\n- Pricing and resource limits may change without notice\n- Blue Lobster may terminate access at its sole discretion\n\n\n","version":"0.0.1"},"paths":{"/api/v1/health":{"get":{"tags":["HEALTH"],"summary":"Check API health","description":"Performs a basic health check of the API service and its dependencies.\n\n        ## Endpoint\n        GET /api/v1/health\n\n        ## Response States\n        - healthy: All systems operational\n        - degraded: Some systems impaired but service available\n        - unhealthy: Critical systems unavailable","operationId":"health_check_api_v1_health_get","responses":{"200":{"description":"Service is healthy","content":{"application/json":{"schema":{},"example":{"status":"healthy","timestamp":"2024-01-15T10:30:00Z","components":{"api":"operational","redis":"operational","postgresql":"operational","proxmox":"operational"}}}}}}}},"/api/v1/tasks/{task_id}":{"get":{"tags":["TASKS"],"summary":"Task Status","description":"Retrieves detailed status information for a specific task.\n\n        ## Endpoint\n        GET /api/v1/tasks/{task_id}\n\n        ## Task Lifecycle\n        1. PENDING: Task is queued for processing\n        2. PROCESSING: Task is actively being executed\n        3. COMPLETED: Task finished successfully\n        4. FAILED: Task encountered an error\n\n        ## Response Details\n        - task_id: Unique identifier for the task\n        - status: Current state of the task\n        - operation: Type of operation (create_instance, delete_instance, etc.)\n        - params: Task-specific parameters\n        - created_at: When the task was created\n        - updated_at: Last status update time\n        - message: Additional status details or error message\n        - account_id: Owner of the task\n\n        ## Common Operations\n        - Instance Creation: Usually takes 1-2 minutes\n        - Instance Deletion: Usually takes 30-60 seconds\n        - Resource allocation: Usually instant\n\n        ## Error Handling\n        - Returns 404 if task_id not found\n        - Returns 500 if database query fails\n\n        ## Usage Notes\n        - Poll this endpoint to track long-running operations\n        - Recommended polling interval: 2-5 seconds\n        - Task records are retained for 24 hours","operationId":"get_task_status_api_v1_tasks__task_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"Task status retrieved successfully","content":{"application/json":{"schema":{},"example":{"task_id":"task_abc123","status":"PROCESSING","operation":"create_instance","params":{"vm_uuid":"vm-xyz789","host_id":"px1","account_id":"acc_123"},"created_at":"2024-01-15T10:30:00Z","updated_at":"2024-01-15T10:30:05Z","message":"Allocating resources","account_id":"acc_123"}}}},"404":{"description":"Task not found","content":{"application/json":{"example":{"error":"task_not_found","message":"Task not found","task_id":"task_abc123"}}}},"500":{"description":"Server error","content":{"application/json":{"example":{"error":"task_status_failed","message":"Failed to get task status: Database error","task_id":"task_abc123"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tasks":{"get":{"tags":["TASKS"],"summary":"List Tasks","description":"Returns a list of recent tasks for the authenticated account.\n\n        ## Endpoint\n        GET /api/v1/tasks\n\n        ## Query Parameters\n        - `limit`: Maximum number of tasks to return (default: 50, max: 100)\n        - `days`: Number of days to look back (default: 1, max: 7)\n        - `status`: Filter by task status (optional, e.g., \"PENDING\", \"PROCESSING\", \"COMPLETED\", \"FAILED\")\n\n        ## Response Details\n        - List of tasks sorted by creation time (newest first)\n        - Each task includes ID, status, operation type, timestamps, and user identifiers\n\n        ## Usage Notes\n        - Default timeframe is 1 day\n        - Tasks older than 7 days may be automatically purged\n        - Use status filter to find specific task states","operationId":"list_tasks_api_v1_tasks_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Days"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"List of tasks","content":{"application/json":{"schema":{},"example":{"tasks":[{"task_id":"task_abc123","status":"COMPLETED","operation":"create_instance","created_at":"2024-01-15T10:30:00Z","updated_at":"2024-01-15T10:35:00Z","message":"VM created successfully","auth_token_partial":"AuSpn7JK","client_ip":"38.29.145.16"}],"total":1,"limit":50,"days":1}}}},"401":{"description":"Authentication failed","content":{"application/json":{"example":{"error":"unauthorized","message":"Invalid or missing API key"}}}},"403":{"description":"Permission denied","content":{"application/json":{"example":{"error":"forbidden","message":"Staff permission required to view all accounts"}}}},"500":{"description":"Server error","content":{"application/json":{"example":{"error":"query_failed","message":"Failed to retrieve tasks","request_id":"req_abc123"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/templates":{"get":{"tags":["INSTANCES"],"summary":"List available templates","description":"List all available VM templates that can be used when creating instances.","operationId":"list_templates_api_v1_instances_templates_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"List of available templates","content":{"application/json":{"schema":{}}}},"403":{"description":"Permission denied"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances":{"get":{"tags":["INSTANCES"],"summary":"List Instances","description":"Returns a list of all active virtual machine instances for the authenticated account.\n\n        ## Endpoint\n        GET /api/v1/instances\n\n        ## Response Fields\n        - uuid: Unique identifier for the instance\n        - name: User-assigned instance name\n        - host_id: Data center identifier (e.g., px1)\n        - region: Geographic region where instance is deployed (e.g., us-east-dev)\n        - ip_address: Public IPv4 address\n        - cpu_cores: Number of virtual CPU cores\n        - memory: RAM in GB\n        - storage: Disk size in GB\n        - gpu_count: Number of attached GPUs\n        - gpu_model: GPU model (if applicable)\n        - power_status: Power state of the Instance\n        - created_at: UTC timestamp of creation\n        - metadata: Optional key-value pairs for tracking and organization\n\n        ## Resource Information\n        - cpu_cores: Shows allocated vCPU cores (1-64)\n        - memory: Shows allocated RAM in GB (8-512)\n        - storage: Shows allocated disk space in GB (40-4096)\n        - gpu_count: Shows number of GPUs attached (0-8)\n\n        ## Sorting\n        - Instances are sorted by creation date (newest first)\n        - All times are in UTC","operationId":"list_instances_api_v1_instances_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"List of Instances","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VMInstance"},"title":"Response List Instances Api V1 Instances Get"},"example":[{"uuid":"vm-abc123","name":"ml-training-1","host_id":"px1","region":"us-east-dev","ip_address":"111.111.111.111","cpu_cores":8,"memory":32,"storage":100,"gpu_count":1,"gpu_model":"RTX A5000","power_status":"running","created_at":"2024-01-15T10:30:00Z","metadata":{"project":"ml-training","department":"research","owner":"john.doe"}}]}}},"401":{"description":"Authentication failed","content":{"application/json":{"example":{"error":"unauthorized","message":"Invalid or missing API key"}}}},"500":{"description":"Server error","content":{"application/json":{"example":{"error":"query_failed","message":"Failed to retrieve instances","request_id":"req_abc123","timestamp":"2024-01-15T10:30:00Z"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/available":{"get":{"tags":["INSTANCES"],"summary":"Available Instances","description":"This API call lists all available instance types and their configurations, along with current capacity in each region.\n\n        ## Endpoint\n        GET /api/v1/instances/available\n\n        ## Instance Types Include:\n        - CPU-only instances (various sizes)\n        - Single GPU instances (A4000, A5000, A6000, etc.)\n        - Multi-GPU instances (up to 8 GPUs)\n\n        ## Response Details:\n        - Available instance types with full specifications\n        - Current capacity status by region\n        - Pricing in cents per hour\n        - GPU model and memory details, where applicable\n\n        ## Resource Specifications:\n        - CPU cores: 1-128 cores\n        - Memory: 8-1024 GB\n        - Storage: 40-4096 GB\n        - GPUs: 0-8 per instance\n\n        ## Notes:\n        - All instances run Ubuntu 22.04 with NVIDIA drivers pre-installed\n        - Capacity is checked in real-time\n        - Only regions with available capacity are listed\n        - Prices and configurations are subject to change\n        - GPU availability varies by region","operationId":"get_available_instances_api_v1_instances_available_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"List of available instance types and their configurations","content":{"application/json":{"schema":{},"example":{"data":[{"id":"v1_cpu_medium","instance_type":{"name":"v1_cpu_medium","description":"CPU Only Instance","gpu_description":"N/A - CPU Only","price_cents_per_hour":6,"specs":{"vcpus":4,"memory_gib":16,"storage_gib":250,"gpus":0}},"regions_with_capacity_available":[{"name":"us-east-dev","description":"Philadelphia, PA","location":{"city":"Philadelphia","state":"PA","country":"US"}}]},{"id":"gpu_1x_a4000","instance_type":{"name":"gpu_1x_a4000","description":"Single GPU Instance","gpu_description":"NVIDIA RTX A4000 (16GB VRAM)","price_cents_per_hour":45,"specs":{"vcpus":8,"memory_gib":32,"storage_gib":250,"gpus":1,"gpu_model":"A4000"}},"regions_with_capacity_available":[{"name":"us-east-dev","description":"Philadelphia, PA","location":{"city":"Philadelphia","state":"PA","country":"US"}}]}]}}}},"401":{"description":"Authentication failed","content":{"application/json":{"example":{"error":"unauthorized","message":"Invalid or missing API key"}}}},"403":{"description":"Permission denied","content":{"application/json":{"example":{"error":"forbidden","message":"Write permission required"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/launch-instance":{"post":{"tags":["INSTANCES"],"summary":"Launch Standard Instance","description":"Creates a new instance using standardized configurations. This is the recommended way to launch instances.\n\n        ## Endpoint\n        POST /api/v1/instances/launch-instance\n\n        ## Required Fields\n        - `region`: Region where instance will be deployed (e.g., \"us-east-1\")\n        - `instance_type_name`: Configuration template (e.g., \"gpu_1x_a4000\")\n        - `ssh_key_names`: List of SSH key names to install (first key is primary)\n\n        ## Optional Fields\n        - `name`: Custom name for the instance (default: auto-generated)\n        - `metadata`: Key-value pairs for tracking and organization\n\n        ## Instance Types\n        Use GET /api/v1/instances to see available configurations:\n        - CPU-only instances (v1_cpu_small, v1_cpu_medium, etc.)\n        - Single GPU instances (gpu_1x_a4000, gpu_1x_a5000, etc.)\n        - Multi-GPU instances (gpu_2x_a4000, gpu_4x_a5000, etc.)\n\n        ## Important Notes\n        - Creation takes 1-10 minutes (typically 1-2 minutes)\n        - SSH key must be registered before launching\n        - Instance will auto-start after creation\n        - Billing begins when instance is ready\n        - Failed creations are not billed\n\n        ## Example Request\n        ```json\n        {\n            \"region\": \"us-east-1\",\n            \"instance_type\": \"gpu_1x_a4000\",\n            \"ssh_key\": \"ssh-rsa AAAA...\",\n            \"name\": \"my-gpu-instance\",\n            \"metadata\": {\n                \"project\": \"training-job\",\n                \"id\": \"01\",\n                \"owner\": \"john.doe\"\n            }\n        }\n        ```","operationId":"launch_standard_instance_api_v1_instances_launch_instance_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaunchInstanceRequest"}}}},"responses":{"200":{"description":"Instance launch initiated successfully","content":{"application/json":{"schema":{},"example":{"data":{"instance_ids":["vm-abc123"],"task_id":"task_xyz789","assigned_ip":"111.111.111.111","status":"PENDING","timestamp":"2024-01-15T10:30:00Z","next_steps":{"description":"Your Instance creation request has been queued. Please check the task status endpoint to monitor progress.","task_status_endpoint":"/api/v1/tasks/task_xyz789","expected_states":{"PENDING":"Task is queued for processing","PROCESSING":"Instance is being created","COMPLETED":"Instance creation successful - instance details will be available","FAILED":"Instance creation failed - check error message for details"}}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"example":{"error":"invalid_request","message":"Invalid instance type or region specified","details":{"valid_instance_types":["v1_cpu_medium","gpu_1x_a4000"],"valid_regions":["us-east-1","us-east-dev"]}}}}},"401":{"description":"Authentication failed","content":{"application/json":{"example":{"error":"unauthorized","message":"Invalid or missing API key"}}}},"403":{"description":"Permission denied","content":{"application/json":{"example":{"error":"forbidden","message":"Buyer permission required"}}}},"409":{"description":"Resource conflict","content":{"application/json":{"example":{"error":"resource_conflict","message":"Requested resources not available in specified region"}}}},"500":{"description":"Server error","content":{"application/json":{"example":{"error":"launch_failed","message":"Failed to initiate instance creation","task_id":"task_xyz789"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/launch-custom":{"post":{"tags":["INSTANCES"],"summary":"Launch Custom Instance","description":"Creates a fully customized Instance with exact resource specifications.\n\n        ## Endpoint\n        POST /api/v1/instances/launch-custom\n\n        ## Requires elevated permissions - email support@bluelobster.ai for access\n\n        ## Process Overview\n        1. Check available resources with GET /api/v1/resources\n        2. Configure Instance specs based on available capacity\n        3. Launch instance with custom specifications\n        4. Monitor creation via task ID\n\n        ## Required Fields\n        - `name`: Instance hostname (alphanumeric and hyphens only)\n        - `host`: Host ID where Instance will be created (e.g., \"px1\")\n        - `cores`: Number of CPU cores (1-64)\n        - `memory`: RAM in GB (8-512, must be even)\n        - `disk_size`: Storage in GB (40-4096)\n        - `gpu_count`: Number of GPUs (0-8)\n        - `template_name`: OS template (e.g., \"UBUNTU-22-04-NV\")\n        - `username`: Main account username\n\n        ## Authentication Methods (One Required)\n        - `password`: Account password\n        - `ssh_key`: SSH public key\n\n        ## Optional Fields\n        - `metadata`: Key-value pairs for tracking and organization\n\n        ## Resource Planning Example\n        1. Check available resources:\n        ```bash\n        curl -X GET \"https://api.bluelobster.ai/api/v1/resources\" \\\n             -H \"X-API-Key: your-api-key\"\n        ```\n\n        2. Example response showing available resources:\n        ```json\n        {\n            \"hosts\": {\n                \"px1\": {\n                    \"city\": \"Philadelphia\",\n                    \"state\": \"PA\",\n                    \"region\": \"us-east-dev\",\n                    \"status\": \"available\",\n                    \"cores_available\": 128,\n                    \"memory_available\": 512,\n                    \"storage_available\": 2048,\n                    \"gpu_model\": \"A4000\",\n                    \"gpus_available\": 4\n                }\n            }\n        }\n        ```\n\n        3. Launch custom instance based on available resources:\n        ```json\n        {\n            \"name\": \"custom-gpu-instance\",\n            \"host\": \"px1\",\n            \"cores\": 16,\n            \"memory\": 64,\n            \"disk_size\": 200,\n            \"gpu_count\": 2,\n            \"template_name\": \"UBUNTU-22-04-NV\",\n            \"username\": \"ubuntu\",\n            \"ssh_key\": \"ssh-rsa AAAA...\",\n            \"metadata\": {\n                \"project\": \"ml-training\",\n                \"department\": \"research\",\n                \"owner\": \"john.doe\"\n            }\n        }\n        ```\n\n        ## Important Notes\n        - Requires elevated permissions - contact Blue Lobster staff for access\n        - Resources are validated against host capacity\n        - Creation takes 1-10 minutes (typically 1-2 minutes)\n        - Billing begins when instance is ready\n        - Failed creations are not billed\n\n        ## Resource Limits\n        - CPU: 1-64 cores (must be power of 2 except for single core)\n        - Memory: 8-512 GB (must be even number)\n        - Storage: 40-4096 GB\n        - GPUs: 0-8 per instance\n\n        ## Available Templates\n        - UBUNTU-22-04-NV: Ubuntu 22.04 with NVIDIA drivers\n        - UBUNTU-22-04: Ubuntu 22.04 base image\n        - WIN10: Windows 10 with Cloudbase-Init\n        - More templates available on request\n\n        ## Windows Template Notes\n        For Windows templates (e.g., WIN10):\n        - **Password**: If no password is provided, a secure 16-character random password\n          is automatically generated and returned in the response `credentials` field.\n        - **IMPORTANT**: The generated password is shown ONLY ONCE in the creation response.\n          Store it securely as it cannot be retrieved later.\n        - SSH keys are supported via OpenSSH Server (pre-installed)\n        - RDP is enabled by default on Windows templates\n        - Default username is \"bluelobster\" if not specified\n\n        ## Windows VM Example\n        ```json\n        {\n            \"name\": \"windows-workstation\",\n            \"host\": \"px1\",\n            \"cores\": 8,\n            \"memory\": 16,\n            \"disk_size\": 100,\n            \"gpu_count\": 1,\n            \"template_name\": \"WIN10\",\n            \"username\": \"admin\"\n        }\n        ```\n\n        Response includes auto-generated credentials:\n        ```json\n        {\n            \"task_id\": \"task_abc123\",\n            \"vm_uuid\": \"vm_xyz789\",\n            \"credentials\": {\n                \"username\": \"admin\",\n                \"password\": \"K8#mP2$nX9@vL4qR\",\n                \"note\": \"This password is shown only once. Store it securely.\"\n            }\n        }\n        ```","operationId":"launch_custom_instance_api_v1_instances_launch_custom_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVMRequest"}}}},"responses":{"200":{"description":"Instance launch initiated successfully","content":{"application/json":{"schema":{},"examples":{"linux_vm":{"summary":"Linux VM Creation","value":{"task_id":"task_abc123","vm_uuid":"vm_xyz789","assigned_ip":"111.111.111.111","status":"PENDING","timestamp":"2024-01-15T10:30:00Z","next_steps":{"description":"Your Instance creation request has been queued. Please check the task status endpoint to monitor progress.","task_status_endpoint":"/api/v1/tasks/task_abc123","expected_states":{"PENDING":"Task is queued for processing","PROCESSING":"Instance is being created","COMPLETED":"Instance creation successful - instance details will be available","FAILED":"Instance creation failed - check error message for details"}}}},"windows_vm":{"summary":"Windows VM with Auto-generated Password","value":{"task_id":"task_def456","vm_uuid":"vm_win101","assigned_ip":"111.111.111.112","status":"PENDING","timestamp":"2024-01-15T10:35:00Z","credentials":{"username":"bluelobster","password":"K8#mP2$nX9@vL4qR","note":"This password is shown only once. Store it securely. You can use it for RDP/VNC access."},"next_steps":{"description":"Your Instance creation request has been queued. Please check the task status endpoint to monitor progress.","task_status_endpoint":"/api/v1/tasks/task_def456","expected_states":{"PENDING":"Task is queued for processing","PROCESSING":"Instance is being created","COMPLETED":"Instance creation successful - instance details will be available","FAILED":"Instance creation failed - check error message for details"}}}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"example":{"error":"invalid_request","message":"Invalid resource specifications","details":{"memory":"Must be an even number between 8 and 512","cores":"Must be a power of 2 between 1 and 64"}}}}},"403":{"description":"Permission denied","content":{"application/json":{"example":{"error":"forbidden","message":"Staff permission required"}}}},"409":{"description":"Resource conflict","content":{"application/json":{"example":{"error":"resource_conflict","message":"Requested resources not available on specified host","available_resources":{"cores":32,"memory":128,"storage":1024,"gpus":2}}}}},"500":{"description":"Server error","content":{"application/json":{"example":{"error":"launch_failed","message":"Failed to initiate instance creation","task_id":"task_xyz789"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}":{"get":{"tags":["INSTANCES"],"summary":"Instance Details","description":"Retrieves comprehensive details about a specific virtual machine instance.\n\n        ## Endpoint\n        GET /api/v1/instances/{instance_id}\n\n        ## Response Fields\n        - uuid: Unique identifier for the Instance\n        - name: User-assigned instance name\n        - host_id: Data center identifier (e.g., px1)\n        - region: Geographic region where instance is deployed (e.g., us-east-dev)\n        - ip_address: Public IPv4 address\n        - cpu_cores: Number of virtual CPU cores\n        - memory: RAM in GB\n        - storage: Disk size in GB\n        - gpu_count: Number of attached GPUs\n        - gpu_model: GPU model (if applicable)\n        - power_status: Power state of the Instance\n        - created_at: UTC timestamp of creation\n        - metadata: Optional key-value pairs for tracking and organization\n\n        ## Power States\n        - power_status:\n            - running: Instance is powered on and accessible\n            - stopped: Instance is powered off but retained\n            - paused: Instance is in suspended state\n            - unknown: Power state could not be determined\n\n        ## Resource Information\n        - cpu_cores: Shows allocated vCPU cores (1-64)\n        - memory: Shows allocated RAM in GB (8-512)\n        - storage: Shows allocated disk space in GB (40-4096)\n        - gpu_count: Shows number of GPUs attached (0-8)\n\n        ## Usage Notes\n        - Refresh as needed for updated status\n        - IP address may be null during provisioning\n        - GPU count shows total assigned GPUs\n        - Use metadata for instance tracking\n\n        ## Common Issues\n        - Instance not found: Check instance ID\n        - Missing IP: Instance may still be provisioning\n        - Status mismatch: May need to wait for sync","operationId":"get_instance_api_v1_instances__instance_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"Instance details retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VMInstance"},"example":{"uuid":"vm-abc123","name":"ml-training-1","host_id":"px1","region":"us-east-dev","ip_address":"111.111.111.111","cpu_cores":8,"memory":32,"storage":100,"gpu_count":1,"gpu_model":"RTX A5000","power_status":"running","created_at":"2024-01-15T10:30:00Z","metadata":{"project":"ml-training","department":"research","owner":"john.doe"}}}}},"404":{"description":"Instance not found","content":{"application/json":{"example":{"error":"instance_not_found","message":"Instance vm-abc123 not found"}}}},"500":{"description":"Server error","content":{"application/json":{"example":{"error":"query_failed","message":"Failed to get instance details: Database error","request_id":"req_abc123"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["INSTANCES"],"summary":"Delete Instance","description":"Deletes an instance and releases all associated resources.\n\n        ## Endpoint\n        DELETE /api/v1/instances/{instance_id}\n\n        ## Important Notes\n        - Operation is irreversible\n        - ALL DATA WILL BE LOST\n        - Billing stops after successful deletion\n\n        ## Best Practices\n        - Backup important data before deletion\n        - Verify instance ID carefully\n        - Monitor deletion task status","operationId":"delete_instance_api_v1_instances__instance_id__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}}],"responses":{"200":{"description":"Instance deleted successfully","content":{"application/json":{"schema":{},"example":{"status":"success","message":"Instance deleted successfully","instance_id":"vm-abc123","host":"px1"}}}},"404":{"description":"Instance not found","content":{"application/json":{"example":{"error":"instance_not_found","message":"Instance vm-abc123 not found"}}}},"400":{"description":"Invalid state for deletion","content":{"application/json":{"example":{"error":"invalid_state","message":"VM is not in 'rented' status: terminating"}}}},"500":{"description":"Deletion failed","content":{"application/json":{"example":{"error":"deletion_failed","message":"Failed to delete VM: timeout waiting for Proxmox task completion"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/reboot":{"post":{"tags":["INSTANCES"],"summary":"Reboot an instance","description":"Performs a hard reboot of the specified instance.\n\n        ## Endpoint\n        POST /api/v1/instances/{instance_id}/reboot\n\n        ## Best Practices\n        - Save work before rebooting\n        - Verify instance state after reboot\n        - Check task logs if reboot fails\n        - Use during maintenance windows","operationId":"reboot_instance_api_v1_instances__instance_id__reboot_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}}],"responses":{"200":{"description":"Reboot completed successfully","content":{"application/json":{"schema":{},"example":{"status":"success","message":"Instance rebooted successfully","instance_id":"vm-abc123","host":"px1","duration_ms":15234}}}},"404":{"description":"Instance not found","content":{"application/json":{"example":{"error":"instance_not_found","message":"Instance vm-abc123 not found"}}}},"409":{"description":"Instance operation in progress","content":{"application/json":{"example":{"error":"operation_in_progress","message":"Another operation is in progress on this Instance"}}}},"500":{"description":"Reboot failed","content":{"application/json":{"example":{"error":"reboot_failed","message":"Failed to reboot Instance: timeout waiting for power state"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/shutdown":{"post":{"tags":["INSTANCES"],"summary":"Shutdown an instance","description":"Performs a graceful shutdown of the specified instance.\n\n        ## Endpoint\n        POST /api/v1/instances/{instance_id}/shutdown\n\n        ## Best Practices\n        - Save work before shutting down\n        - Use this for graceful OS shutdown\n        - Instance will need to be powered on again to use","operationId":"shutdown_instance_api_v1_instances__instance_id__shutdown_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}}],"responses":{"200":{"description":"Shutdown task queued successfully","content":{"application/json":{"schema":{},"example":{"task_id":"task_abc123","status":"PENDING","message":"VM shutdown queued","instance_id":"vm-abc123","host":"px1"}}}},"404":{"description":"Instance not found","content":{"application/json":{"example":{"error":"instance_not_found","message":"Instance vm-abc123 not found"}}}},"500":{"description":"Shutdown failed","content":{"application/json":{"example":{"error":"shutdown_failed","message":"Failed to shutdown instance"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/force-shutdown":{"post":{"tags":["INSTANCES"],"summary":"Force shutdown an instance","description":"Performs an immediate forced shutdown of the specified instance.\n\n        ## Endpoint\n        POST /api/v1/instances/{instance_id}/force-shutdown\n\n        ## Best Practices\n        - Use only when graceful shutdown fails\n        - May cause data loss if writes are in progress\n        - Equivalent to pulling the power plug","operationId":"force_shutdown_instance_api_v1_instances__instance_id__force_shutdown_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}}],"responses":{"200":{"description":"Force shutdown task queued successfully","content":{"application/json":{"schema":{},"example":{"task_id":"task_abc123","status":"PENDING","message":"VM force shutdown queued","instance_id":"vm-abc123","host":"px1"}}}},"404":{"description":"Instance not found","content":{"application/json":{"example":{"error":"instance_not_found","message":"Instance vm-abc123 not found"}}}},"500":{"description":"Force shutdown failed","content":{"application/json":{"example":{"error":"force_shutdown_failed","message":"Failed to force shutdown instance"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/power-on":{"post":{"tags":["INSTANCES"],"summary":"Power on an instance","description":"Powers on a stopped instance.\n\n        ## Endpoint\n        POST /api/v1/instances/{instance_id}/power-on\n\n        ## Best Practices\n        - Instance must be in stopped state\n        - Wait for task completion before accessing instance","operationId":"power_on_instance_api_v1_instances__instance_id__power_on_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}}],"responses":{"200":{"description":"Power on task queued successfully","content":{"application/json":{"schema":{},"example":{"task_id":"task_abc123","status":"PENDING","message":"VM power on queued","instance_id":"vm-abc123","host":"px1"}}}},"404":{"description":"Instance not found","content":{"application/json":{"example":{"error":"instance_not_found","message":"Instance vm-abc123 not found"}}}},"500":{"description":"Power on failed","content":{"application/json":{"example":{"error":"power_on_failed","message":"Failed to power on instance"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/power-cycle":{"post":{"tags":["INSTANCES"],"summary":"Power cycle an instance","description":"Power cycles an instance (stop + start).\n\n        ## Endpoint\n        POST /api/v1/instances/{instance_id}/power-cycle\n\n        ## When to Use\n        - After renaming an instance (hostname changes require power cycle for cloud-init)\n        - When a simple reboot doesn't resolve issues\n        - Unlike reboot, this fully powers off and restarts the VM\n\n        ## Best Practices\n        - Instance must be in 'rented' status\n        - Wait for task completion before accessing instance","operationId":"power_cycle_instance_api_v1_instances__instance_id__power_cycle_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}}],"responses":{"200":{"description":"Power cycle task queued successfully","content":{"application/json":{"schema":{},"example":{"task_id":"task_abc123","status":"PENDING","message":"VM power cycle queued","instance_id":"vm-abc123","host":"px1"}}}},"404":{"description":"Instance not found","content":{"application/json":{"example":{"error":"instance_not_found","message":"Instance vm-abc123 not found"}}}},"500":{"description":"Power cycle failed","content":{"application/json":{"example":{"error":"power_cycle_failed","message":"Failed to power cycle instance"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/rename":{"put":{"tags":["INSTANCES"],"summary":"Rename Instance","description":"Updates the display name of an existing instance.\n\n        ## Endpoint\n        PUT /api/v1/instances/{instance_id}/rename\n\n        ## Request Body:\n        - **name**: New name for the instance (3-64 characters, alphanumeric with hyphens/underscores)\n\n        ## Notes:\n        - Only the display name is changed; the instance ID remains the same\n        - Name must be unique within your account\n        - Changes take effect immediately","operationId":"rename_instance_api_v1_instances__instance_id__rename_put","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"Instance renamed successfully","content":{"application/json":{"schema":{},"example":{"message":"Instance renamed successfully","instance_id":"550e8400-e29b-41d4-a716-446655440000","new_name":"my-production-server"}}}},"400":{"description":"Invalid name format","content":{"application/json":{"example":{"error":"invalid_name","message":"Name must be 3-64 characters, alphanumeric with hyphens/underscores only"}}}},"404":{"description":"Instance not found","content":{"application/json":{"example":{"error":"not_found","message":"Instance not found"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/log":{"post":{"tags":["INSTANCES"],"summary":"Instance Log","description":"Retrieves instance history with billing summary for the authenticated account\n        within the specified time range.\n\n        ## Endpoint\n        POST /api/v1/instances/log\n\n        ## Time Range Requirements\n        - Must be in ISO format (YYYY-MM-DDTHH:MM:SSZ)\n        - start_time must be before end_time\n        - Maximum date range is 90 days\n\n        ## Response Details\n        - Total record count\n        - Time range used for query\n        - List of instances sorted by creation time (newest first)\n\n        ## Instance Fields\n        - **uuid**: Unique instance identifier\n        - **name**: Instance name\n        - **host_id**: Host server identifier\n        - **vmid**: Proxmox VM ID\n        - **status**: Current state (creating, rented, deleted)\n        - **ip_address**: Assigned public IP (CIDR notation)\n        - **cpu_cores**, **memory_gb**, **disk_gb**, **gpu_count**: Resources\n        - **instance_type**: Instance type (e.g. v1_gpu_a4000_small)\n        - **template_name**: OS template used\n        - **price_cents_per_hour**: Hourly rate in cents\n        - **created_at**, **updated_at**, **deleted_at**: Lifecycle timestamps\n\n        ## Billing Fields (per instance)\n        - **total_billed_cents**: Total amount charged for this instance\n        - **total_hours_billed**: Total hours billed\n        - **first_billed_at**: Start of first billing period\n        - **last_billed_at**: End of most recent billing period\n\n        ## Common Use Cases\n        - Audit instance lifecycle and costs\n        - Reconcile billing with usage\n        - Track resource consumption over time","operationId":"get_instance_log_api_v1_instances_log_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceLogRequest"}}},"required":true},"responses":{"200":{"description":"Instance history retrieved successfully","content":{"application/json":{"schema":{},"example":{"total_records":1,"time_range":{"start":"2026-04-01T00:00:00Z","end":"2026-04-14T23:59:59Z"},"instances":[{"uuid":"e0aad74c-7520-4575-88b0-746649a91201","name":"my-gpu-instance","host_id":"wil-gpu-26","vmid":11143,"status":"deleted","ip_address":"38.29.145.239/24","cpu_cores":32,"memory_gb":128,"disk_gb":1000,"gpu_count":4,"instance_type":"v1_gpu_a6000_large","template_name":"UBUNTU-22-04-NV","price_cents_per_hour":120,"created_at":"2026-04-11T15:43:15Z","updated_at":"2026-04-12T11:21:48Z","deleted_at":"2026-04-12T11:21:48Z","total_billed_cents":2340,"total_hours_billed":19.5,"first_billed_at":"2026-04-11T15:43:15Z","last_billed_at":"2026-04-12T11:21:48Z"}]}}}},"422":{"description":"Invalid time range","content":{"application/json":{"example":{"error":"invalid_time_range","message":"Maximum time range is 90 days"}}}},"500":{"description":"Database query failed","content":{"application/json":{"example":{"error":"query_failed","message":"Failed to retrieve instance history","details":"Database connection error"}}}}},"security":[{"APIKeyHeader":[]}]}},"/api/v1/instances/{instance_id}/stats":{"get":{"tags":["INSTANCES","MONITORING"],"summary":"Get Instance Statistics","description":"Get real-time CPU, memory, disk I/O, and network statistics for an instance.\n\n        ## Endpoint\n        GET /api/v1/instances/{instance_id}/stats\n\n        ## Response Details:\n        - **cpu**: CPU usage percentage and core count\n        - **memory**: Memory usage in bytes and percentage\n        - **disk**: Disk read/write bytes per second\n        - **network**: Network in/out bytes per second\n        - **uptime**: Instance uptime in seconds\n\n        ## Notes:\n        - Statistics are collected in real-time from the hypervisor\n        - Values may be 0 if the instance is stopped\n        - Disk and network stats are cumulative since instance start","operationId":"get_instance_stats_api_v1_instances__instance_id__stats_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"Instance statistics","content":{"application/json":{"schema":{},"example":{"instance_id":"550e8400-e29b-41d4-a716-446655440000","status":"running","cpu":{"usage_percent":25.5,"cores":8},"memory":{"used_bytes":8589934592,"total_bytes":17179869184,"usage_percent":50.0},"disk":{"read_bytes_sec":1048576,"write_bytes_sec":524288},"network":{"in_bytes_sec":102400,"out_bytes_sec":51200},"uptime_seconds":86400}}}},"404":{"description":"Instance not found","content":{"application/json":{"example":{"error":"not_found","message":"Instance not found"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/console":{"post":{"tags":["INSTANCES","CONSOLE"],"summary":"Get Console Access Ticket","description":"Get a VNC proxy ticket for remote console access to the instance.\n\n        ## Endpoint\n        GET /api/v1/instances/{instance_id}/console\n\n        ## Response Details:\n        - **ticket**: Authentication ticket for VNC connection\n        - **port**: VNC proxy port number\n        - **host**: Hostname for VNC connection\n        - **expires_at**: Ticket expiration timestamp\n\n        ## Usage:\n        Use the returned ticket with a noVNC client or compatible VNC viewer to connect to the instance console.\n\n        ## Notes:\n        - Tickets expire after a short period (typically 30 seconds)\n        - Instance must be running to get console access\n        - Console provides full keyboard and display access","operationId":"get_console_ticket_api_v1_instances__instance_id__console_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"Console ticket generated","content":{"application/json":{"schema":{},"example":{"instance_id":"550e8400-e29b-41d4-a716-446655440000","ticket":"PVEVNC:...","port":5900,"host":"phl-gpu-01.bluelobster.ai","expires_at":"2024-01-15T12:00:30Z"}}}},"400":{"description":"Instance not running","content":{"application/json":{"example":{"error":"invalid_state","message":"Instance must be running to access console"}}}},"404":{"description":"Instance not found","content":{"application/json":{"example":{"error":"not_found","message":"Instance not found"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/backup":{"post":{"tags":["INSTANCES","BACKUPS"],"summary":"Create Instance Backup","description":"Create a backup of the instance to Proxmox Backup Server (PBS) storage.\n\n        ## Endpoint\n        POST /api/v1/instances/{instance_id}/backup\n\n        ## Backup Process:\n        1. A background task is created to perform the backup\n        2. The instance continues running during backup (live backup)\n        3. Backup is stored on PBS with automatic deduplication\n        4. Progress can be monitored via the task status endpoint\n\n        ## Notes:\n        - Backups are stored regionally on PBS storage\n        - Only one backup or restore operation can run per instance at a time\n        - Backup time depends on disk size and data changed since last backup\n        - Incremental backups are used when possible for efficiency\n\n        ## Limitations:\n        - Cannot start backup while restore is in progress\n        - Cannot start backup while another backup is running","operationId":"create_instance_backup_api_v1_instances__instance_id__backup_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"Backup task created","content":{"application/json":{"schema":{},"example":{"message":"Backup started","task_id":"550e8400-e29b-41d4-a716-446655440000","instance_id":"660e8400-e29b-41d4-a716-446655440001"}}}},"409":{"description":"Conflicting operation in progress","content":{"application/json":{"example":{"error":"task_in_progress","message":"Cannot start backup: restore is already in progress for this instance"}}}},"404":{"description":"Instance not found","content":{"application/json":{"example":{"error":"instance_not_found","message":"Instance 550e8400-e29b-41d4-a716-446655440000 not found"}}}},"500":{"description":"Backup failed to start","content":{"application/json":{"example":{"error":"backup_failed","message":"Failed to create backup task"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/backups":{"get":{"tags":["INSTANCES","BACKUPS"],"summary":"List Instance Backups","description":"List all available backups for an instance.\n\n        ## Endpoint\n        GET /api/v1/instances/{instance_id}/backups\n\n        ## Response Details:\n        - **backups**: Array of available backup snapshots\n        - **backup_in_progress**: Details if a backup is currently running\n        - **restore_in_progress**: Details if a restore is currently running\n        - **storage**: PBS storage identifier\n        - **total**: Total number of backups available\n\n        ## Backup Object Properties:\n        - **volid**: Unique backup volume identifier (used for restore)\n        - **size_bytes**: Backup size in bytes\n        - **size_human**: Human-readable size (e.g., \"45.2 GB\")\n        - **created_at**: ISO timestamp of backup creation\n        - **format**: Backup format (typically \"pbs-vm\")\n        - **notes**: Optional backup notes/description\n\n        ## Notes:\n        - Backups are listed from newest to oldest\n        - Use the volid to restore from a specific backup","operationId":"list_instance_backups_api_v1_instances__instance_id__backups_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"List of available backups","content":{"application/json":{"schema":{},"example":{"instance_id":"550e8400-e29b-41d4-a716-446655440000","storage":"wil-pbs-01","backups":[{"volid":"wil-pbs-01:backup/vm/100/2024-01-15T10:30:00Z","size_bytes":48530000000,"size_human":"45.2 GB","created_at":"2024-01-15T10:30:00Z","format":"pbs-vm"},{"volid":"wil-pbs-01:backup/vm/100/2024-01-14T10:30:00Z","size_bytes":47200000000,"size_human":"44.0 GB","created_at":"2024-01-14T10:30:00Z","format":"pbs-vm"}],"total":2}}}},"404":{"description":"Instance not found","content":{"application/json":{"example":{"error":"instance_not_found","message":"Instance 550e8400-e29b-41d4-a716-446655440000 not found"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/restore":{"post":{"tags":["INSTANCES","BACKUPS"],"summary":"Restore Instance from Backup","description":"Restore an instance from a backup snapshot.\n\n        ## Endpoint\n        POST /api/v1/instances/{instance_id}/restore\n\n        ## Request Body:\n        - **backup_volid**: The volume ID of the backup to restore (from list backups response)\n\n        ## Restore Process:\n        1. Instance is stopped if running\n        2. Current disk is replaced with backup data\n        3. Instance is automatically started after restore completes\n        4. Progress can be monitored via the task status endpoint\n\n        ## WARNING:\n        **This operation is destructive!** All current instance data will be overwritten with the backup data.\n        Any changes made since the backup was created will be lost.\n\n        ## Notes:\n        - Only one backup or restore operation can run per instance at a time\n        - Cannot restore while backup is in progress\n        - Restore time depends on backup size\n        - Instance will be started automatically after successful restore\n\n        ## Limitations:\n        - Cannot restore from an in-progress backup\n        - Cannot start restore while another backup/restore is running","operationId":"restore_instance_backup_api_v1_instances__instance_id__restore_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"Restore task created","content":{"application/json":{"schema":{},"example":{"message":"Restore started","task_id":"550e8400-e29b-41d4-a716-446655440000","instance_id":"660e8400-e29b-41d4-a716-446655440001","backup_volid":"wil-pbs-01:backup/vm/100/2024-01-15T10:30:00Z"}}}},"400":{"description":"Invalid request","content":{"application/json":{"example":{"error":"missing_backup_volid","message":"backup_volid is required"}}}},"409":{"description":"Conflicting operation in progress","content":{"application/json":{"example":{"error":"task_in_progress","message":"Cannot start restore: backup is already in progress for this instance"}}}},"404":{"description":"Instance not found","content":{"application/json":{"example":{"error":"instance_not_found","message":"Instance 550e8400-e29b-41d4-a716-446655440000 not found"}}}},"500":{"description":"Restore failed to start","content":{"application/json":{"example":{"error":"restore_failed","message":"Failed to create restore task"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/team":{"put":{"tags":["INSTANCES"],"summary":"Assign VM to team","description":"Assign a VM to a team. Only account owners/admins can assign VMs to teams.","operationId":"assign_vm_to_team_api_v1_instances__instance_id__team_put","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"VM assigned to team successfully","content":{"application/json":{"schema":{}}}},"403":{"description":"Permission denied"},"404":{"description":"VM or team not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["INSTANCES"],"summary":"Remove VM from team","description":"Remove a VM from its team. Only account owners/admins can remove VMs from teams.","operationId":"remove_vm_from_team_api_v1_instances__instance_id__team_delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"VM removed from team successfully","content":{"application/json":{"schema":{}}}},"403":{"description":"Permission denied"},"404":{"description":"VM not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/teams/{team_id}/instances":{"get":{"tags":["INSTANCES"],"summary":"List VMs in team","description":"List all VMs assigned to a specific team.","operationId":"list_team_instances_api_v1_teams__team_id__instances_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"team_id","in":"path","required":true,"schema":{"type":"string","title":"Team Id"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"List of VMs in the team","content":{"application/json":{"schema":{}}}},"403":{"description":"Permission denied"},"404":{"description":"Team not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/ips":{"get":{"tags":["INSTANCES"],"summary":"List Instance IP Addresses","description":"Get all IP addresses assigned to an instance.","operationId":"list_instance_ips_api_v1_instances__instance_id__ips_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}}],"responses":{"200":{"description":"List of IP addresses","content":{"application/json":{"schema":{}}}},"404":{"description":"Instance not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["INSTANCES"],"summary":"Assign Additional IP","description":"Assign an additional IP address and network interface to an instance. Billed at $3.00/month.","operationId":"assign_instance_ip_api_v1_instances__instance_id__ips_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}}],"responses":{"200":{"description":"IP assigned successfully","content":{"application/json":{"schema":{}}}},"400":{"description":"No available IPs or invalid state"},"404":{"description":"Instance not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/ips/{ip_address}":{"delete":{"tags":["INSTANCES"],"summary":"Release IP Address","description":"Release an additional IP address from an instance. Cannot release primary IP or last IP.","operationId":"release_instance_ip_api_v1_instances__instance_id__ips__ip_address__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}},{"name":"ip_address","in":"path","required":true,"schema":{"type":"string","title":"Ip Address"}}],"responses":{"200":{"description":"IP released successfully","content":{"application/json":{"schema":{}}}},"400":{"description":"Cannot release primary or last IP"},"404":{"description":"Instance or IP not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/backups":{"get":{"tags":["BACKUPS"],"summary":"List all backups","description":"List all backups for the authenticated account across all VMs (including deleted VMs). For team-scoped tokens, only backups from VMs in that team are returned.","operationId":"list_all_backups_api_v1_backups_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"List of backups","content":{"application/json":{"schema":{}}}},"500":{"description":"Server error"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["BACKUPS"],"summary":"Delete a backup","description":"Delete a backup from PBS storage. Creates a background task to handle the deletion. This cannot be undone.","operationId":"delete_backup_api_v1_backups_delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"volid","in":"query","required":true,"schema":{"type":"string","description":"PBS volume ID of the backup to delete","title":"Volid"},"description":"PBS volume ID of the backup to delete"},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"Delete task created","content":{"application/json":{"schema":{}}}},"403":{"description":"Access denied"},"404":{"description":"Backup not found"},"409":{"description":"Delete already in progress"},"500":{"description":"Server error"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/backups/restore":{"post":{"tags":["BACKUPS"],"summary":"Restore backup to VM","description":"Restore a backup to any compatible VM. The target VM's disk must be >= backup size.","operationId":"restore_backup_to_vm_api_v1_backups_restore_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"volid","in":"query","required":true,"schema":{"type":"string","description":"PBS volume ID of the backup","title":"Volid"},"description":"PBS volume ID of the backup"},{"name":"target_vm_uuid","in":"query","required":true,"schema":{"type":"string","description":"UUID of the VM to restore to","title":"Target Vm Uuid"},"description":"UUID of the VM to restore to"},{"name":"new_name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional new name for VM after restore","title":"New Name"},"description":"Optional new name for VM after restore"},{"name":"add_restore_prefix","in":"query","required":false,"schema":{"type":"boolean","description":"Add 'RESTORE-{date}-' prefix to VM name","default":false,"title":"Add Restore Prefix"},"description":"Add 'RESTORE-{date}-' prefix to VM name"},{"name":"backup_source_name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Source VM name from backup (used for prefix)","title":"Backup Source Name"},"description":"Source VM name from backup (used for prefix)"},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"Restore task created","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid request"},"403":{"description":"Access denied - backup not owned by account"},"404":{"description":"Backup or VM not found"},"500":{"description":"Server error"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/backups/storage":{"get":{"tags":["BACKUPS"],"summary":"Get backup storage summary","description":"Get total backup storage used by account with billing breakdown.","operationId":"get_backup_storage_api_v1_backups_storage_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"Storage summary","content":{"application/json":{"schema":{}}}},"500":{"description":"Server error"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/backups/notes":{"put":{"tags":["BACKUPS"],"summary":"Update backup notes","description":"Update the notes for a backup.","operationId":"update_backup_notes_api_v1_backups_notes_put","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"volid","in":"query","required":true,"schema":{"type":"string","description":"PBS volume ID","title":"Volid"},"description":"PBS volume ID"},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupNotesUpdate"}}}},"responses":{"200":{"description":"Notes updated","content":{"application/json":{"schema":{}}}},"404":{"description":"Backup not found"},"500":{"description":"Server error"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{vm_uuid}/backup-schedule":{"get":{"tags":["BACKUPS"],"summary":"Get backup schedule for VM","description":"Get the backup schedule configuration for a specific VM.","operationId":"get_backup_schedule_api_v1_instances__vm_uuid__backup_schedule_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"vm_uuid","in":"path","required":true,"schema":{"type":"string","title":"Vm Uuid"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"Schedule data","content":{"application/json":{"schema":{}}}},"404":{"description":"VM or schedule not found"},"500":{"description":"Server error"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["BACKUPS"],"summary":"Create or update backup schedule","description":"Create or update the backup schedule for a VM. Only one schedule per VM.","operationId":"create_backup_schedule_api_v1_instances__vm_uuid__backup_schedule_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"vm_uuid","in":"path","required":true,"schema":{"type":"string","title":"Vm Uuid"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackupScheduleCreate"}}}},"responses":{"200":{"description":"Schedule created/updated","content":{"application/json":{"schema":{}}}},"400":{"description":"Invalid schedule"},"404":{"description":"VM not found"},"500":{"description":"Server error"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["BACKUPS"],"summary":"Delete backup schedule","description":"Delete the backup schedule for a VM.","operationId":"delete_backup_schedule_api_v1_instances__vm_uuid__backup_schedule_delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"vm_uuid","in":"path","required":true,"schema":{"type":"string","title":"Vm Uuid"}},{"name":"_mark_section","in":"query","required":false,"schema":{"title":" Mark Section"}}],"responses":{"200":{"description":"Schedule deleted","content":{"application/json":{"schema":{}}}},"404":{"description":"VM or schedule not found"},"500":{"description":"Server error"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/firewall":{"get":{"tags":["FIREWALL"],"summary":"Get Firewall Status","description":"Get the current firewall configuration for an instance, including enabled status, policies, and rules.\n\n        ## Endpoint\n        GET /api/v1/instances/{instance_id}/firewall\n\n        ## Response Details:\n        - **enabled**: Whether the firewall is active\n        - **policy_in**: Default policy for inbound traffic (ACCEPT or DROP)\n        - **policy_out**: Default policy for outbound traffic (ACCEPT or DROP)\n        - **rules**: List of configured firewall rules\n\n        ## Rule Properties:\n        - **pos**: Rule position/priority (lower = higher priority)\n        - **type**: Direction - 'in' (inbound) or 'out' (outbound)\n        - **action**: ACCEPT, DROP, or REJECT\n        - **proto**: Protocol (tcp, udp, icmp)\n        - **dport**: Destination port(s)\n        - **sport**: Source port(s)\n        - **source**: Source IP/CIDR (e.g., '192.168.1.0/24')\n        - **dest**: Destination IP/CIDR\n        - **comment**: Rule description\n        - **enable**: Whether rule is active (1=enabled, 0=disabled)\n\n        ## Permissions:\n        Requires owner, admin, or member role on the instance's team.","operationId":"get_instance_firewall_api_v1_instances__instance_id__firewall_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}}],"responses":{"200":{"description":"Firewall configuration retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FirewallStatus"},"example":{"enabled":true,"policy_in":"DROP","policy_out":"ACCEPT","rules":[{"pos":0,"type":"in","action":"ACCEPT","proto":"tcp","dport":"22","comment":"SSH access","enable":1},{"pos":1,"type":"in","action":"ACCEPT","proto":"tcp","dport":"80,443","comment":"Web traffic","enable":1},{"pos":2,"type":"in","action":"ACCEPT","proto":"tcp","dport":"3306","source":"10.0.0.0/8","comment":"MySQL from private network","enable":1}]}}}},"403":{"description":"Permission denied","content":{"application/json":{"example":{"error":"forbidden","message":"Your team role 'viewer' cannot manage firewall. Required: owner, admin, or member"}}}},"404":{"description":"Instance not found","content":{"application/json":{"example":{"error":"instance_not_found","message":"Instance 550e8400-e29b-41d4-a716-446655440000 not found"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["FIREWALL"],"summary":"Update Firewall Settings","description":"Enable/disable the firewall and set default inbound/outbound policies.\n\n        ## Endpoint\n        PUT /api/v1/instances/{instance_id}/firewall\n\n        ## Request Body:\n        - **enable**: Boolean to enable (true) or disable (false) the firewall\n        - **policy_in**: Default inbound policy - 'ACCEPT' or 'DROP'\n        - **policy_out**: Default outbound policy - 'ACCEPT' or 'DROP'\n\n        ## Policy Behavior:\n        - **DROP policy**: All traffic is blocked unless explicitly allowed by a rule\n        - **ACCEPT policy**: All traffic is allowed unless explicitly blocked by a rule\n\n        ## Important Notes:\n        - When enabling firewall with DROP inbound policy, ensure you have an SSH rule configured\n        - Changes take effect immediately\n        - Outbound is typically set to ACCEPT to allow the instance to reach the internet\n\n        ## Permissions:\n        Requires owner, admin, or member role on the instance's team.","operationId":"update_instance_firewall_api_v1_instances__instance_id__firewall_put","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FirewallOptions"}}}},"responses":{"200":{"description":"Firewall settings updated","content":{"application/json":{"schema":{},"example":{"status":"success","message":"Firewall options updated","firewall":{"enabled":true,"policy_in":"DROP","policy_out":"ACCEPT","rules":[]}}}}},"403":{"description":"Permission denied"},"404":{"description":"Instance not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/firewall/rules":{"post":{"tags":["FIREWALL"],"summary":"Add Firewall Rule","description":"Add a new firewall rule to the instance.\n\n        ## Endpoint\n        POST /api/v1/instances/{instance_id}/firewall/rules\n\n        ## Request Body:\n        - **type** (required): Rule direction - 'in' or 'out'\n        - **action** (required): 'ACCEPT', 'DROP', or 'REJECT'\n        - **proto**: Protocol - 'tcp', 'udp', 'icmp' (default: tcp)\n        - **dport**: Destination port(s) - single (22), range (8000:9000), or list (80,443)\n        - **sport**: Source port(s) - same format as dport\n        - **source**: Source IP address or CIDR (e.g., '192.168.1.100' or '10.0.0.0/8')\n        - **dest**: Destination IP address or CIDR\n        - **comment**: Description of the rule\n        - **enable**: 1 to enable (default), 0 to disable\n\n        ## Common Rule Examples:\n\n        ### Allow SSH from anywhere:\n        ```json\n        {\n            \"type\": \"in\",\n            \"action\": \"ACCEPT\",\n            \"proto\": \"tcp\",\n            \"dport\": \"22\",\n            \"comment\": \"SSH access\"\n        }\n        ```\n\n        ### Allow HTTP/HTTPS:\n        ```json\n        {\n            \"type\": \"in\",\n            \"action\": \"ACCEPT\",\n            \"proto\": \"tcp\",\n            \"dport\": \"80,443\",\n            \"comment\": \"Web traffic\"\n        }\n        ```\n\n        ### Allow MySQL only from specific IP:\n        ```json\n        {\n            \"type\": \"in\",\n            \"action\": \"ACCEPT\",\n            \"proto\": \"tcp\",\n            \"dport\": \"3306\",\n            \"source\": \"203.0.113.50\",\n            \"comment\": \"MySQL from office\"\n        }\n        ```\n\n        ### Allow private network access:\n        ```json\n        {\n            \"type\": \"in\",\n            \"action\": \"ACCEPT\",\n            \"proto\": \"tcp\",\n            \"dport\": \"1:65535\",\n            \"source\": \"10.0.0.0/8\",\n            \"comment\": \"All TCP from private network\"\n        }\n        ```\n\n        ### Block specific IP:\n        ```json\n        {\n            \"type\": \"in\",\n            \"action\": \"DROP\",\n            \"source\": \"192.168.1.100\",\n            \"comment\": \"Block bad actor\"\n        }\n        ```\n\n        ## Notes:\n        - Rules are evaluated in order (position 0 first)\n        - First matching rule wins\n        - If no rule matches, the default policy applies","operationId":"add_firewall_rule_api_v1_instances__instance_id__firewall_rules_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FirewallRule"}}}},"responses":{"200":{"description":"Rule created","content":{"application/json":{"schema":{},"example":{"status":"success","message":"Firewall rule added","rule":{"pos":0,"type":"in","action":"ACCEPT","proto":"tcp","dport":"22","comment":"SSH access"}}}}},"400":{"description":"Invalid rule parameters","content":{"application/json":{"example":{"error":"invalid_rule","message":"Invalid port format: must be 1-65535"}}}},"403":{"description":"Permission denied"},"404":{"description":"Instance not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/instances/{instance_id}/firewall/rules/{pos}":{"delete":{"tags":["FIREWALL"],"summary":"Delete Firewall Rule","description":"Delete a firewall rule by its position.\n\n        ## Endpoint\n        DELETE /api/v1/instances/{instance_id}/firewall/rules/{pos}\n\n        ## Path Parameters:\n        - **instance_id**: UUID of the instance\n        - **pos**: Rule position (0-based index from the rules list)\n\n        ## Notes:\n        - Get the rule position from the GET /firewall endpoint\n        - Deleting a rule may change positions of subsequent rules\n        - Changes take effect immediately\n\n        ## Permissions:\n        Requires owner, admin, or member role on the instance's team.","operationId":"delete_firewall_rule_api_v1_instances__instance_id__firewall_rules__pos__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}},{"name":"pos","in":"path","required":true,"schema":{"type":"integer","title":"Pos"}}],"responses":{"200":{"description":"Rule deleted","content":{"application/json":{"schema":{},"example":{"status":"success","message":"Firewall rule at position 0 deleted"}}}},"403":{"description":"Permission denied"},"404":{"description":"Instance or rule not found","content":{"application/json":{"example":{"error":"rule_not_found","message":"Rule at position 5 not found"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["FIREWALL"],"summary":"Get Firewall Rule","description":"Get details of a specific firewall rule by position.\n\n        ## Endpoint\n        GET /api/v1/instances/{instance_id}/firewall/rules/{pos}\n\n        ## Path Parameters:\n        - **instance_id**: UUID of the instance\n        - **pos**: Rule position (0-based index)\n\n        ## Permissions:\n        Requires owner, admin, or member role on the instance's team.","operationId":"get_firewall_rule_api_v1_instances__instance_id__firewall_rules__pos__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}},{"name":"pos","in":"path","required":true,"schema":{"type":"integer","title":"Pos"}}],"responses":{"200":{"description":"Rule details","content":{"application/json":{"schema":{},"example":{"pos":0,"type":"in","action":"ACCEPT","proto":"tcp","dport":"22","source":"10.0.0.0/8","comment":"SSH from private network","enable":1}}}},"403":{"description":"Permission denied"},"404":{"description":"Instance or rule not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"BackupNotesUpdate":{"properties":{"notes":{"type":"string","title":"Notes"}},"type":"object","required":["notes"],"title":"BackupNotesUpdate"},"BackupScheduleCreate":{"properties":{"frequency":{"type":"string","title":"Frequency"},"hour_utc":{"type":"integer","title":"Hour Utc"},"day_of_week":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Day Of Week"},"day_of_month":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Day Of Month"}},"type":"object","required":["frequency","hour_utc"],"title":"BackupScheduleCreate"},"CreateVMRequest":{"properties":{"name":{"type":"string","maxLength":64,"minLength":1,"pattern":"^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$","title":"Name","description":"VM hostname (alphanumeric and hyphens only)","example":"my-gpu-instance"},"instance_type":{"type":"string","title":"Instance Type","description":"Instance type (determines pricing). Use /api/v1/instances to list available types."},"price_cents_per_hour":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Price Cents Per Hour","description":"Ignored - price is determined server-side from instance_type"},"host":{"type":"string","maxLength":100,"minLength":1,"title":"Host","description":"Host ID where VM will be created (validated against database)","example":"phl-gpu-01"},"metadata":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Metadata","description":"Optional metadata key-value pairs for tracking and organization","example":{"department":"research","owner":"john.doe","project":"ml-training"}},"cores":{"type":"integer","maximum":64.0,"minimum":1.0,"title":"Cores","description":"Number of CPU cores","example":4},"memory":{"type":"integer","maximum":512.0,"minimum":8.0,"title":"Memory","description":"Memory in GB","example":16},"disk_size":{"type":"integer","maximum":4096.0,"minimum":30.0,"title":"Disk Size","description":"Disk size in GB","example":100},"template_name":{"anyOf":[{"type":"string","pattern":"^[A-Z0-9-]+$"},{"type":"null"}],"title":"Template Name","description":"OS template to use (from /instances/templates). Either template_name OR iso_url required.","example":"UBUNTU-22-04-NV"},"iso_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Iso Url","description":"URL to an ISO image (max 4GB) to download for OS installation. Either template_name OR iso_url required. VM will boot from ISO for manual installation.","example":"https://example.com/windows10.iso"},"gpu_count":{"type":"integer","maximum":8.0,"minimum":0.0,"title":"Gpu Count","description":"Number of GPUs","example":1},"username":{"type":"string","maxLength":32,"minLength":1,"pattern":"^[a-zA-Z][a-zA-Z0-9-]*$","title":"Username","description":"Username for main account (lowercase for Linux, can be uppercase for Windows)","example":"ubuntu"},"password":{"anyOf":[{"type":"string","maxLength":64,"minLength":8,"pattern":"^[^ \"'`;|<>{}\\\\]*$"},{"type":"null"}],"title":"Password","description":"Password for main account"},"ssh_key":{"anyOf":[{"type":"string","pattern":"^(ssh-rsa|ssh-ed25519|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521) [A-Za-z0-9+/]+[=]{0,3}( .+)?$"},{"type":"null"}],"title":"Ssh Key","description":"SSH public key"}},"type":"object","required":["name","instance_type","host","cores","memory","disk_size","gpu_count","username"],"title":"CreateVMRequest","description":"Request model for creating a custom VM instance.\n\nNote: Business logic validation (resource availability, host existence, template existence)\nis performed in the route handlers, not in this model. This keeps the model focused on\nformat validation only."},"FirewallOptions":{"properties":{"enable":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enable","description":"Enable or disable firewall"},"policy_in":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Policy In","description":"Default inbound policy: 'ACCEPT' or 'DROP'"},"policy_out":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Policy Out","description":"Default outbound policy: 'ACCEPT' or 'DROP'"}},"type":"object","title":"FirewallOptions","description":"Firewall options for a VM."},"FirewallRule":{"properties":{"type":{"type":"string","title":"Type","description":"Rule direction: 'in' or 'out'"},"action":{"type":"string","title":"Action","description":"Action: 'ACCEPT', 'DROP', or 'REJECT'"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source","description":"Source IP/CIDR (e.g., '192.168.1.0/24')"},"dest":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dest","description":"Destination IP/CIDR"},"proto":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Proto","description":"Protocol: tcp, udp, icmp, etc."},"dport":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dport","description":"Destination port or range (e.g., '22' or '80:443')"},"sport":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sport","description":"Source port or range"},"comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Comment","description":"Rule description"},"enable":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Enable","description":"1 to enable, 0 to disable","default":1}},"type":"object","required":["type","action"],"title":"FirewallRule","description":"A firewall rule definition."},"FirewallStatus":{"properties":{"enabled":{"type":"boolean","title":"Enabled"},"policy_in":{"type":"string","title":"Policy In"},"policy_out":{"type":"string","title":"Policy Out"},"rules":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Rules"}},"type":"object","required":["enabled","policy_in","policy_out","rules"],"title":"FirewallStatus","description":"Current firewall status and rules."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"InstanceLogRequest":{"properties":{"start_time":{"type":"string","format":"date-time","title":"Start Time","description":"Start time for log query (ISO format)","example":"2024-01-01T00:00:00Z"},"end_time":{"type":"string","format":"date-time","title":"End Time","description":"End time for log query (ISO format)","example":"2024-01-31T23:59:59Z"}},"type":"object","required":["start_time","end_time"],"title":"InstanceLogRequest","description":"Request model for querying instance logs.","example":{"end_time":"2024-01-31T23:59:59Z","start_time":"2024-01-01T00:00:00Z"}},"LaunchInstanceRequest":{"properties":{"region":{"type":"string","title":"Region","description":"Region where instance will be deployed","example":"us-east-1"},"instance_type":{"type":"string","title":"Instance Type","description":"Instance type configuration to use","example":"gpu_1x_a4000"},"ssh_key":{"anyOf":[{"type":"string","pattern":"^(ssh-rsa|ssh-ed25519|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521) [A-Za-z0-9+/]+[=]{0,3}( .+)?$"},{"type":"null"}],"title":"Ssh Key","description":"SSH public key (required for Linux templates)"},"password":{"anyOf":[{"type":"string","maxLength":64,"minLength":8,"pattern":"^[^ \"'`;|<>{}\\\\]*$"},{"type":"null"}],"title":"Password","description":"Password for the account (required for Windows templates)"},"username":{"type":"string","maxLength":32,"minLength":1,"pattern":"^[a-zA-Z][a-zA-Z0-9-]*$","title":"Username","description":"Username for main account (required)","example":"myusername"},"name":{"anyOf":[{"type":"string","maxLength":64,"pattern":"^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$"},{"type":"null"}],"title":"Name","description":"Custom name for the instance"},"metadata":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Metadata","description":"Optional metadata key-value pairs for tracking and organization","example":{"department":"research","owner":"john.doe","project":"ml-training"}},"template_name":{"anyOf":[{"type":"string","pattern":"^[A-Z0-9-]+$"},{"type":"null"}],"title":"Template Name","description":"OS template to use. Defaults based on instance type (GPU instances get NVIDIA template, non-GPU get base). Use /instances/templates to list available templates.","example":"UBUNTU-22-04-NV"},"iso_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Iso Url","description":"URL to an ISO image to download for OS installation. ISO will be attached as CD-ROM and VM will boot from it. Max 4GB. Use for custom OS like Windows, SteamOS, etc.","example":"https://example.com/windows10.iso"}},"type":"object","required":["region","instance_type","username"],"title":"LaunchInstanceRequest","description":"Request model for launching a standard instance."},"VMInstance":{"properties":{"uuid":{"type":"string","title":"Uuid"},"name":{"type":"string","title":"Name"},"host_id":{"type":"string","title":"Host Id"},"region":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region"},"ip_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip Address"},"internal_ip":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Internal Ip"},"cpu_cores":{"type":"integer","title":"Cpu Cores"},"memory":{"type":"integer","title":"Memory"},"storage":{"type":"integer","title":"Storage"},"gpu_count":{"type":"integer","title":"Gpu Count","default":0},"gpu_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gpu Model"},"power_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Power Status"},"created_at":{"type":"string","title":"Created At"},"metadata":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Metadata"},"instance_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Instance Type"},"price_cents_per_hour":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Price Cents Per Hour"},"team_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team Id"},"team_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team Name"},"access_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Access Type"},"template_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Template Name"},"template_display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Template Display Name"},"os_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Os Type"},"vm_username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vm Username"}},"type":"object","required":["uuid","name","host_id","ip_address","cpu_cores","memory","storage","power_status","created_at"],"title":"VMInstance","description":"Response model for VM instance data."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"APIKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key"}}},"tags":[{"name":"INSTANCES","description":"Operations for creating, managing, and deleting instances"},{"name":"BACKUPS","description":"Backup and restore operations for instances"},{"name":"CONSOLE","description":"Remote console access to instances"},{"name":"MONITORING","description":"Real-time instance metrics and statistics"},{"name":"TASKS","description":"Asynchronous task management"},{"name":"RESOURCES","description":"Fine grain resource management (requires staff approval)"},{"name":"HEALTH","description":"API health monitoring"},{"name":"FIREWALL","description":"Instance firewall management - control inbound/outbound traffic rules"}]}