hypersdk

HyperSDK REST API Documentation

Overview

The HyperSDK REST API provides programmatic access to manage VM migration jobs, schedules, webhooks, and more. All endpoints return JSON responses and use standard HTTP methods and status codes.

Base URL: http://localhost:8080 (configurable)

Authentication: Currently no authentication (add in production)

Table of Contents


Health & Status

GET /health

Health check endpoint.

Response:

{
  "status": "ok"
}

GET /status

Get current daemon status and statistics.

Response:

{
  "total_jobs": 42,
  "running_jobs": 3,
  "completed_jobs": 35,
  "failed_jobs": 4,
  "worker_count": 10,
  "active_workers": 3
}

Jobs API

POST /jobs/submit

Submit a new migration job.

Request Body:

{
  "vm_path": "Datacenter/vm/production/web-server-1",
  "source": {
    "type": "vsphere",
    "vcenter_url": "vcenter.example.com",
    "username": "admin@vsphere.local",
    "password": "password",
    "datacenter": "Datacenter"
  },
  "destination": {
    "type": "kvm",
    "libvirt_uri": "qemu+ssh://user@host/system"
  },
  "options": {
    "conversion_method": "vddk",
    "network_mapping": {
      "VM Network": "br0"
    }
  }
}

Response:

{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "message": "job submitted successfully"
}

Status Codes:

POST /jobs/query

Query jobs with filters.

Request Body:

{
  "all": true,
  "status": "running",
  "limit": 10
}

Response:

{
  "jobs": [
    {
      "definition": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "vm_path": "Datacenter/vm/production/web-server-1"
      },
      "status": "running",
      "progress": {
        "stage": "conversion",
        "percent_complete": 45,
        "current_bytes": 21474836480,
        "total_bytes": 53687091200
      },
      "started_at": "2026-01-17T10:30:00Z",
      "error": null
    }
  ],
  "total": 1
}

Status Codes:

GET /jobs/{id}

Get specific job details.

URL Parameters:

Response:

{
  "definition": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "vm_path": "Datacenter/vm/production/web-server-1"
  },
  "status": "running",
  "progress": {
    "stage": "conversion",
    "percent_complete": 45
  }
}

Status Codes:

POST /jobs/cancel

Cancel jobs by ID or status.

Request Body:

{
  "job_ids": ["550e8400-e29b-41d4-a716-446655440000"],
  "status": "running"
}

Response:

{
  "message": "jobs cancelled successfully",
  "count": 1
}

Status Codes:


Schedules API

GET /schedules

List all scheduled jobs.

Response:

{
  "schedules": [
    {
      "id": "daily-backup",
      "name": "Daily VM Backup",
      "schedule": "0 2 * * *",
      "enabled": true,
      "job_template": {
        "vm_path": "Datacenter/vm/production/*",
        "source": {...},
        "destination": {...}
      },
      "last_run": "2026-01-17T02:00:00Z",
      "next_run": "2026-01-18T02:00:00Z",
      "run_count": 30
    }
  ],
  "total": 1,
  "timestamp": "2026-01-17T12:00:00Z"
}

POST /schedules

Create a new scheduled job.

Request Body:

{
  "id": "daily-backup",
  "name": "Daily VM Backup",
  "description": "Backup production VMs every night",
  "schedule": "0 2 * * *",
  "enabled": true,
  "job_template": {
    "vm_path": "Datacenter/vm/production/web-server-1",
    "source": {...},
    "destination": {...}
  }
}

Schedule Format: Cron expression (minute hour day month weekday)

Response:

{
  "message": "schedule created successfully",
  "schedule": {...}
}

Status Codes:

GET /schedules/{id}

Get specific schedule.

Response:

{
  "id": "daily-backup",
  "name": "Daily VM Backup",
  "schedule": "0 2 * * *",
  "enabled": true,
  "last_run": "2026-01-17T02:00:00Z",
  "next_run": "2026-01-18T02:00:00Z"
}

PUT /schedules/{id}

Update schedule.

Request Body:

{
  "name": "Updated Name",
  "schedule": "0 3 * * *",
  "enabled": true
}

Response:

{
  "message": "schedule updated successfully"
}

DELETE /schedules/{id}

Delete schedule.

Response:

{
  "message": "schedule deleted successfully"
}

POST /schedules/{id}/enable

Enable schedule.

Response:

{
  "message": "schedule enabled successfully"
}

POST /schedules/{id}/disable

Disable schedule.

Response:

{
  "message": "schedule disabled successfully"
}

POST /schedules/{id}/trigger

Manually trigger schedule execution.

Response:

{
  "message": "schedule triggered successfully"
}

GET /schedules/stats

Get schedule statistics.

Response:

{
  "total_schedules": 5,
  "enabled_schedules": 3,
  "disabled_schedules": 2,
  "total_runs": 150,
  "successful_runs": 145,
  "failed_runs": 5
}

Webhooks API

GET /webhooks

List all configured webhooks.

Response:

{
  "webhooks": [
    {
      "url": "https://hooks.example.com/notify",
      "events": ["job.completed", "job.failed"],
      "enabled": true,
      "timeout": 30,
      "retry_count": 3
    }
  ],
  "total": 1,
  "timestamp": "2026-01-17T12:00:00Z"
}

POST /webhooks

Add new webhook.

Request Body:

{
  "url": "https://hooks.example.com/notify",
  "events": ["job.completed", "job.failed"],
  "enabled": true,
  "timeout": 30,
  "retry_count": 3,
  "headers": {
    "Authorization": "Bearer token123"
  }
}

Available Events:

Response:

{
  "message": "webhook added successfully",
  "webhook": {...}
}

DELETE /webhooks/{index}

Delete webhook by index.

URL Parameters:

Response:

{
  "message": "webhook deleted successfully"
}

POST /webhooks/test

Test webhook delivery.

Request Body:

{
  "url": "https://hooks.example.com/notify",
  "event": "test"
}

Response:

{
  "message": "test webhook sent"
}

VM Discovery API

GET /vms/list

List VMs from vCenter.

Query Parameters:

Response:

{
  "vms": [
    {
      "name": "web-server-1",
      "path": "Datacenter/vm/production/web-server-1",
      "power_state": "poweredOn",
      "num_cpu": 4,
      "memory_mb": 8192,
      "storage": 107374182400,
      "guest_os": "Ubuntu Linux (64-bit)",
      "ip_address": "192.168.1.10"
    }
  ],
  "total": 1
}

GET /vms/info

Get detailed VM information.

Query Parameters:

Response:

{
  "name": "web-server-1",
  "path": "Datacenter/vm/production/web-server-1",
  "uuid": "42329208-8c5a-3254-1234-567890abcdef",
  "power_state": "poweredOn",
  "hardware": {
    "num_cpu": 4,
    "memory_mb": 8192,
    "num_virtual_disks": 2
  },
  "disks": [
    {
      "label": "Hard disk 1",
      "capacity_kb": 104857600,
      "file_path": "[datastore1] web-server-1/web-server-1.vmdk"
    }
  ]
}

POST /vms/shutdown

Gracefully shutdown VM.

Request Body:

{
  "vcenter_url": "vcenter.example.com",
  "username": "admin@vsphere.local",
  "password": "password",
  "vm_path": "Datacenter/vm/production/web-server-1"
}

Response:

{
  "message": "VM shutdown initiated"
}

POST /vms/poweroff

Force power off VM.

Request Body: Same as shutdown

Response:

{
  "message": "VM powered off"
}

POST /vms/remove-cdrom

Remove CD-ROM devices from VM.

Request Body: Same as shutdown

Response:

{
  "message": "CD-ROM devices removed"
}

WebSocket API

WS /ws

WebSocket endpoint for real-time updates.

Connection:

const ws = new WebSocket('ws://localhost:8080/ws');

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  console.log(message);
};

Message Format:

{
  "type": "status|jobs|job_update|schedule_event",
  "timestamp": "2026-01-17T12:00:00Z",
  "data": {...}
}

Message Types:

  1. status - Status update (every 2 seconds)
    {
      "type": "status",
      "data": {
     "total_jobs": 42,
     "running_jobs": 3,
     "completed_jobs": 35,
     "failed_jobs": 4
      }
    }
    
  2. jobs - Initial job list on connection
    {
      "type": "jobs",
      "data": {
     "jobs": [...]
      }
    }
    
  3. job_update - Real-time job update
    {
      "type": "job_update",
      "data": {
     "definition": {...},
     "status": "running",
     "progress": {...}
      }
    }
    
  4. schedule_event - Schedule event
    {
      "type": "schedule_event",
      "data": {
     "schedule_id": "daily-backup",
     "event": "triggered|completed|failed"
      }
    }
    

Features:


Metrics API

GET /metrics

Prometheus metrics endpoint.

Note: Must be enabled in configuration:

metrics:
  enabled: true
  port: 8080

Response: Prometheus text format

# HELP hypersdk_api_requests_total Total API requests
# TYPE hypersdk_api_requests_total counter
hypersdk_api_requests_total{method="GET",path="/status",status="OK"} 1234

# HELP hypersdk_api_request_duration_seconds API request duration
# TYPE hypersdk_api_request_duration_seconds histogram
hypersdk_api_request_duration_seconds_bucket{method="GET",path="/status",le="0.1"} 1200

# HELP hypersdk_jobs_total Total jobs by status
# TYPE hypersdk_jobs_total gauge
hypersdk_jobs_total{status="completed"} 35
hypersdk_jobs_total{status="running"} 3
hypersdk_jobs_total{status="failed"} 4

Available Metrics:


Error Responses

All endpoints use standard HTTP status codes and return errors in this format:

{
  "error": "descriptive error message"
}

Common Status Codes:


Configuration

Example Configuration File

# config.yaml
database:
  path: "/var/lib/hypersdk/jobs.db"

metrics:
  enabled: true
  port: 8080

webhooks:
  - url: "https://hooks.example.com/notify"
    events:
      - job.completed
      - job.failed
    enabled: true
    timeout: 30
    retry_count: 3
    headers:
      Authorization: "Bearer token123"

Client Examples

cURL Examples

Submit Job:

curl -X POST http://localhost:8080/jobs/submit \
  -H "Content-Type: application/json" \
  -d '{
    "vm_path": "Datacenter/vm/test-vm",
    "source": {"type": "vsphere", ...},
    "destination": {"type": "kvm", ...}
  }'

Query Jobs:

curl -X POST http://localhost:8080/jobs/query \
  -H "Content-Type: application/json" \
  -d '{"all": true}'

Create Schedule:

curl -X POST http://localhost:8080/schedules \
  -H "Content-Type: application/json" \
  -d '{
    "id": "nightly-backup",
    "schedule": "0 2 * * *",
    "job_template": {...}
  }'

Python Example

import requests

# Submit job
response = requests.post('http://localhost:8080/jobs/submit', json={
    'vm_path': 'Datacenter/vm/test-vm',
    'source': {'type': 'vsphere', ...},
    'destination': {'type': 'kvm', ...}
})

job_id = response.json()['job_id']
print(f"Job submitted: {job_id}")

# Monitor job
while True:
    job = requests.get(f'http://localhost:8080/jobs/{job_id}').json()
    if job['status'] in ['completed', 'failed']:
        break
    print(f"Progress: {job['progress']['percent_complete']}%")
    time.sleep(5)

JavaScript Example

// Using axios
const axios = require('axios');

// Submit job
const response = await axios.post('http://localhost:8080/jobs/submit', {
  vm_path: 'Datacenter/vm/test-vm',
  source: {type: 'vsphere', ...},
  destination: {type: 'kvm', ...}
});

const jobId = response.data.job_id;

// Connect WebSocket for real-time updates
const ws = new WebSocket('ws://localhost:8080/ws');
ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  if (msg.type === 'job_update' &&
      msg.data.definition.id === jobId) {
    console.log('Progress:', msg.data.progress.percent_complete + '%');
  }
};

Rate Limiting

Currently no rate limiting is implemented. Consider adding in production:


Best Practices

  1. Use WebSocket for real-time updates instead of polling
  2. Handle errors gracefully with exponential backoff
  3. Set timeouts on HTTP requests (recommended: 30s)
  4. Validate input before submitting jobs
  5. Monitor metrics using Prometheus endpoint
  6. Use schedules for recurring migrations
  7. Configure webhooks for event notifications
  8. Test webhooks before production use

Support