# PhotonCloud REST API Guide

**Version:** 1.0
**Last Updated:** 2025-12-12
**Target:** MVP-Alpha Phase

## Overview

PhotonCloud provides REST/HTTP APIs for all core services, enabling easy access via `curl` for:
- 組み込み環境 (Embedded environments)
- Shell scripts and automation
- Debugging and troubleshooting
- Environments without gRPC tooling

All REST APIs follow consistent patterns and run alongside gRPC services on dedicated HTTP ports.

## Service Port Map

| Service | HTTP Port | gRPC Port | Purpose |
|---------|-----------|-----------|---------|
| **ChainFire** | 8081 | 50051 | Distributed KV store with Raft consensus |
| **FlareDB** | 8082 | 50052 | SQL database (KV backend) |
| **IAM** | 8083 | 50051 | Identity & Access Management |
| **PlasmaVMC** | 8084 | 50051 | Virtual Machine Controller |
| **k8shost** | 8085 | 6443 | Kubernetes Host (kubelet replacement) |
| **CreditService** | 8086 | 50057 | Credit/Quota Management |
| **PrismNET** | 8087 | 9090 | Network Management (VPC/Subnet) |
| **NightLight** | 9090 | — | Prometheus TSDB (HTTP-only) |
| **LightningSTOR** | 9000 | — | S3-compatible Object Storage |

## Common Patterns

### Request Format
```bash
# Standard POST request with JSON body
curl -X POST http://localhost:8081/api/v1/kv/mykey/put \
  -H "Content-Type: application/json" \
  -d '{"value": "myvalue"}'
```

### Response Format

**Success Response:**
```json
{
  "data": {
    "id": "resource-id",
    "name": "resource-name",
    ...
  },
  "meta": {
    "request_id": "uuid-v4",
    "timestamp": "2025-12-12T08:30:00Z"
  }
}
```

**Error Response:**
```json
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Resource not found",
    "details": null
  },
  "meta": {
    "request_id": "uuid-v4",
    "timestamp": "2025-12-12T08:30:00Z"
  }
}
```

### Authentication

Most services support multi-tenancy via `org_id` and `project_id`:

```bash
# Query parameters for filtering
curl "http://localhost:8087/api/v1/vpcs?org_id=org-123&project_id=proj-456"

# Request body for creation
curl -X POST http://localhost:8087/api/v1/vpcs \
  -H "Content-Type: application/json" \
  -d '{
    "name": "production-vpc",
    "org_id": "org-123",
    "project_id": "proj-456",
    "cidr_block": "10.0.0.0/16"
  }'
```

For IAM token-based auth:
```bash
# Issue token
TOKEN=$(curl -X POST http://localhost:8083/api/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "principal_id": "user-123",
    "scope_id": "project-456",
    "ttl_seconds": 3600
  }' | jq -r '.data.token')

# Use token in Authorization header
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:8084/api/v1/vms
```

---

## 1. ChainFire (Distributed KV Store)

**Port:** 8081
**Purpose:** Raft-based distributed key-value store with strong consistency

### Health Check
```bash
curl http://localhost:8081/health
```

### Cluster Status
```bash
# Get cluster status (node_id, term, role, is_leader)
curl http://localhost:8081/api/v1/cluster/status
```

**Response:**
```json
{
  "data": {
    "node_id": 1,
    "cluster_id": "cluster-123",
    "term": 42,
    "role": "leader",
    "is_leader": true
  },
  "meta": { ... }
}
```

### KV Operations

**Put Key-Value:**
```bash
curl -X POST http://localhost:8081/api/v1/kv/user:123/put \
  -H "Content-Type: application/json" \
  -d '{"value": "{\"name\":\"alice\",\"email\":\"alice@example.com\"}"}'
```

**Get Value:**
```bash
curl http://localhost:8081/api/v1/kv/user:123
```

**Response:**
```json
{
  "data": {
    "key": "user:123",
    "value": "{\"name\":\"alice\",\"email\":\"alice@example.com\"}"
  },
  "meta": { ... }
}
```

**Delete Key:**
```bash
curl -X POST http://localhost:8081/api/v1/kv/user:123/delete
```

**Range Scan (Prefix Query):**
```bash
# List all keys starting with "user:"
curl "http://localhost:8081/api/v1/kv?prefix=user:"
```

**Response:**
```json
{
  "data": {
    "items": [
      {"key": "user:123", "value": "{...}"},
      {"key": "user:456", "value": "{...}"}
    ]
  },
  "meta": { ... }
}
```

### Cluster Management

**Add Cluster Member:**
```bash
curl -X POST http://localhost:8081/api/v1/cluster/members \
  -H "Content-Type: application/json" \
  -d '{
    "node_id": 2,
    "address": "192.168.1.102:50051"
  }'
```

---

## 2. FlareDB (SQL Database)

**Port:** 8082
**Purpose:** Distributed SQL database with KV backend

### Health Check
```bash
curl http://localhost:8082/health
```

### KV Operations

**Put Key-Value:**
```bash
curl -X PUT http://localhost:8082/api/v1/kv/config:db_version \
  -H "Content-Type: application/json" \
  -d '{
    "value": "1.0.0",
    "namespace": "system"
  }'
```

**Get Value:**
```bash
curl "http://localhost:8082/api/v1/kv/config:db_version?namespace=system"
```

**Response:**
```json
{
  "data": {
    "key": "config:db_version",
    "value": "1.0.0",
    "namespace": "system"
  },
  "meta": { ... }
}
```

**Range Scan:**
```bash
curl "http://localhost:8082/api/v1/scan?start=config:&end=config;&&namespace=system"
```

### SQL Operations (Placeholder)

**Execute SQL:**
```bash
# Note: SQL endpoint is placeholder - use gRPC for full SQL functionality
curl -X POST http://localhost:8082/api/v1/sql \
  -H "Content-Type: application/json" \
  -d '{
    "query": "SELECT * FROM users WHERE id = 123"
  }'
```

**List Tables:**
```bash
# Note: Placeholder endpoint - use gRPC for full functionality
curl http://localhost:8082/api/v1/tables
```

---

## 3. IAM (Identity & Access Management)

**Port:** 8083
**Purpose:** Authentication, authorization, user and policy management

### Health Check
```bash
curl http://localhost:8083/health
```

### Token Operations

**Issue Token:**
```bash
curl -X POST http://localhost:8083/api/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "principal_id": "user-alice",
    "principal_type": "user",
    "scope_id": "project-prod",
    "ttl_seconds": 3600
  }'
```

**Response:**
```json
{
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "expires_at": "2025-12-12T10:30:00Z"
  },
  "meta": { ... }
}
```

**Verify Token:**
```bash
curl -X POST http://localhost:8083/api/v1/auth/verify \
  -H "Content-Type: application/json" \
  -d '{
    "token": "eyJhbGciOiJIUzI1NiIs..."
  }'
```

**Response:**
```json
{
  "data": {
    "valid": true,
    "principal_id": "user-alice",
    "scope_id": "project-prod",
    "expires_at": "2025-12-12T10:30:00Z"
  },
  "meta": { ... }
}
```

### User Management

**Create User:**
```bash
curl -X POST http://localhost:8083/api/v1/users \
  -H "Content-Type: application/json" \
  -d '{
    "id": "user-bob",
    "name": "Bob Smith",
    "email": "bob@example.com",
    "type": "user"
  }'
```

**List Users:**
```bash
curl "http://localhost:8083/api/v1/users?scope_id=project-prod"
```

**Response:**
```json
{
  "data": {
    "users": [
      {
        "id": "user-alice",
        "name": "Alice Johnson",
        "email": "alice@example.com",
        "type": "user"
      },
      {
        "id": "user-bob",
        "name": "Bob Smith",
        "email": "bob@example.com",
        "type": "user"
      }
    ]
  },
  "meta": { ... }
}
```

### Project Management (Placeholder)

```bash
# Note: Project management uses Scope/PolicyBinding in gRPC
# These REST endpoints are placeholders
curl http://localhost:8083/api/v1/projects
curl -X POST http://localhost:8083/api/v1/projects \
  -H "Content-Type: application/json" \
  -d '{"name": "production", "org_id": "org-123"}'
```

---

## 4. PlasmaVMC (Virtual Machine Controller)

**Port:** 8084
**Purpose:** VM lifecycle management (create, start, stop, delete)

### Health Check
```bash
curl http://localhost:8084/health
```

### VM Operations

**List VMs:**
```bash
curl "http://localhost:8084/api/v1/vms?org_id=org-123&project_id=proj-456"
```

**Response:**
```json
{
  "data": {
    "vms": [
      {
        "id": "vm-001",
        "name": "web-server-01",
        "state": "Running",
        "cpus": 4,
        "memory_mb": 8192
      },
      {
        "id": "vm-002",
        "name": "db-server-01",
        "state": "Stopped",
        "cpus": 8,
        "memory_mb": 16384
      }
    ]
  },
  "meta": { ... }
}
```

**Create VM:**
```bash
curl -X POST http://localhost:8084/api/v1/vms \
  -H "Content-Type: application/json" \
  -d '{
    "name": "app-server-03",
    "org_id": "org-123",
    "project_id": "proj-456",
    "vcpus": 2,
    "memory_mib": 4096,
    "hypervisor": "kvm",
    "image_id": "ubuntu-22.04",
    "disk_size_gb": 50
  }'
```

**Response:**
```json
{
  "data": {
    "id": "vm-003",
    "name": "app-server-03",
    "state": "Creating",
    "cpus": 2,
    "memory_mb": 4096
  },
  "meta": { ... }
}
```

**Get VM Details:**
```bash
curl "http://localhost:8084/api/v1/vms/vm-003?org_id=org-123&project_id=proj-456"
```

**Start VM:**
```bash
curl -X POST "http://localhost:8084/api/v1/vms/vm-003/start?org_id=org-123&project_id=proj-456"
```

**Stop VM:**
```bash
curl -X POST "http://localhost:8084/api/v1/vms/vm-003/stop?org_id=org-123&project_id=proj-456" \
  -H "Content-Type: application/json" \
  -d '{"force": false}'
```

**Delete VM:**
```bash
curl -X DELETE "http://localhost:8084/api/v1/vms/vm-003?org_id=org-123&project_id=proj-456"
```

---

## 5. k8shost (Kubernetes Host)

**Port:** 8085
**Purpose:** Kubernetes pod/service/node management (kubelet replacement)

### Health Check
```bash
curl http://localhost:8085/health
```

### Pod Operations

**List Pods:**
```bash
# All namespaces
curl http://localhost:8085/api/v1/pods

# Specific namespace
curl "http://localhost:8085/api/v1/pods?namespace=production"
```

**Response:**
```json
{
  "data": {
    "pods": [
      {
        "name": "nginx-deployment-7d8f9c5b6d-xk2p9",
        "namespace": "production",
        "phase": "Running",
        "pod_ip": "10.244.1.5",
        "node_name": "worker-01"
      }
    ]
  },
  "meta": { ... }
}
```

**Create Pod:**
```bash
curl -X POST http://localhost:8085/api/v1/pods \
  -H "Content-Type: application/json" \
  -d '{
    "name": "nginx-pod",
    "namespace": "production",
    "image": "nginx:1.21",
    "command": ["/bin/sh"],
    "args": ["-c", "nginx -g \"daemon off;\""]
  }'
```

**Delete Pod:**
```bash
curl -X DELETE http://localhost:8085/api/v1/pods/production/nginx-pod
```

### Service Operations

**List Services:**
```bash
curl "http://localhost:8085/api/v1/services?namespace=production"
```

**Response:**
```json
{
  "data": {
    "services": [
      {
        "name": "nginx-service",
        "namespace": "production",
        "type": "ClusterIP",
        "cluster_ip": "10.96.0.100",
        "ports": [
          {"port": 80, "target_port": 8080, "protocol": "TCP"}
        ]
      }
    ]
  },
  "meta": { ... }
}
```

**Create Service:**
```bash
curl -X POST http://localhost:8085/api/v1/services \
  -H "Content-Type: application/json" \
  -d '{
    "name": "app-service",
    "namespace": "production",
    "service_type": "ClusterIP",
    "port": 80,
    "target_port": 8080,
    "selector": {"app": "nginx"}
  }'
```

**Delete Service:**
```bash
curl -X DELETE http://localhost:8085/api/v1/services/production/app-service
```

### Node Operations

**List Nodes:**
```bash
curl http://localhost:8085/api/v1/nodes
```

**Response:**
```json
{
  "data": {
    "nodes": [
      {
        "name": "worker-01",
        "status": "Ready",
        "capacity_cpu": "8",
        "capacity_memory": "16Gi",
        "allocatable_cpu": "7.5",
        "allocatable_memory": "14Gi"
      }
    ]
  },
  "meta": { ... }
}
```

---

## 6. CreditService (Credit/Quota Management)

**Port:** 8086
**Purpose:** Multi-tenant credit tracking, reservations, and billing

### Health Check
```bash
curl http://localhost:8086/health
```

### Wallet Operations

**Create Wallet:**
```bash
curl -X POST http://localhost:8086/api/v1/wallets \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "proj-456",
    "org_id": "org-123",
    "initial_balance": 10000
  }'
```

**Get Wallet Balance:**
```bash
curl http://localhost:8086/api/v1/wallets/proj-456
```

**Response:**
```json
{
  "data": {
    "project_id": "proj-456",
    "org_id": "org-123",
    "balance": 10000,
    "reserved": 2500,
    "available": 7500,
    "currency": "JPY",
    "status": "active"
  },
  "meta": { ... }
}
```

**Top Up Credits:**
```bash
curl -X POST http://localhost:8086/api/v1/wallets/proj-456/topup \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5000,
    "description": "Monthly credit purchase"
  }'
```

**Get Transactions:**
```bash
curl "http://localhost:8086/api/v1/wallets/proj-456/transactions?limit=10"
```

**Response:**
```json
{
  "data": {
    "transactions": [
      {
        "id": "txn-001",
        "project_id": "proj-456",
        "amount": 5000,
        "type": "deposit",
        "description": "Monthly credit purchase",
        "timestamp": "2025-12-12T08:00:00Z"
      },
      {
        "id": "txn-002",
        "project_id": "proj-456",
        "amount": -1500,
        "type": "charge",
        "description": "VM usage charge",
        "resource_id": "vm-003",
        "timestamp": "2025-12-12T09:00:00Z"
      }
    ]
  },
  "meta": { ... }
}
```

### Reservation Operations

**Reserve Credits:**
```bash
curl -X POST http://localhost:8086/api/v1/reservations \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "proj-456",
    "amount": 2000,
    "description": "VM creation reservation",
    "resource_type": "vm",
    "resource_id": "vm-004",
    "ttl_seconds": 3600
  }'
```

**Response:**
```json
{
  "data": {
    "id": "rsv-001",
    "project_id": "proj-456",
    "amount": 2000,
    "status": "active",
    "expires_at": "2025-12-12T10:00:00Z"
  },
  "meta": { ... }
}
```

**Commit Reservation:**
```bash
curl -X POST http://localhost:8086/api/v1/reservations/rsv-001/commit \
  -H "Content-Type: application/json" \
  -d '{
    "actual_amount": 1800,
    "resource_id": "vm-004"
  }'
```

**Release Reservation:**
```bash
curl -X POST http://localhost:8086/api/v1/reservations/rsv-001/release \
  -H "Content-Type: application/json" \
  -d '{
    "reason": "VM creation failed"
  }'
```

---

## 7. PrismNET (Network Management)

**Port:** 8087
**Purpose:** Multi-tenant VPC, subnet, and port management

### Health Check
```bash
curl http://localhost:8087/health
```

### VPC Operations

**List VPCs:**
```bash
curl "http://localhost:8087/api/v1/vpcs?org_id=org-123&project_id=proj-456"
```

**Response:**
```json
{
  "data": {
    "vpcs": [
      {
        "id": "vpc-001",
        "name": "production-vpc",
        "org_id": "org-123",
        "project_id": "proj-456",
        "cidr_block": "10.0.0.0/16",
        "description": "Production environment VPC",
        "status": "active"
      }
    ]
  },
  "meta": { ... }
}
```

**Create VPC:**
```bash
curl -X POST http://localhost:8087/api/v1/vpcs \
  -H "Content-Type: application/json" \
  -d '{
    "name": "staging-vpc",
    "org_id": "org-123",
    "project_id": "proj-456",
    "cidr_block": "172.16.0.0/16",
    "description": "Staging environment VPC"
  }'
```

**Get VPC:**
```bash
curl "http://localhost:8087/api/v1/vpcs/vpc-001?org_id=org-123&project_id=proj-456"
```

**Delete VPC:**
```bash
curl -X DELETE "http://localhost:8087/api/v1/vpcs/vpc-001?org_id=org-123&project_id=proj-456"
```

### Subnet Operations

**List Subnets:**
```bash
curl "http://localhost:8087/api/v1/subnets?vpc_id=vpc-001&org_id=org-123&project_id=proj-456"
```

**Response:**
```json
{
  "data": {
    "subnets": [
      {
        "id": "subnet-001",
        "name": "web-subnet",
        "vpc_id": "vpc-001",
        "cidr_block": "10.0.1.0/24",
        "gateway_ip": "10.0.1.1",
        "description": "Web tier subnet",
        "status": "active"
      },
      {
        "id": "subnet-002",
        "name": "db-subnet",
        "vpc_id": "vpc-001",
        "cidr_block": "10.0.2.0/24",
        "gateway_ip": "10.0.2.1",
        "description": "Database tier subnet",
        "status": "active"
      }
    ]
  },
  "meta": { ... }
}
```

**Create Subnet:**
```bash
curl -X POST http://localhost:8087/api/v1/subnets \
  -H "Content-Type: application/json" \
  -d '{
    "name": "app-subnet",
    "vpc_id": "vpc-001",
    "cidr_block": "10.0.3.0/24",
    "gateway_ip": "10.0.3.1",
    "description": "Application tier subnet"
  }'
```

**Delete Subnet:**
```bash
curl -X DELETE "http://localhost:8087/api/v1/subnets/subnet-003?org_id=org-123&project_id=proj-456&vpc_id=vpc-001"
```

---

## Complete Workflow Examples

### Example 1: Deploy VM with Networking

```bash
# 1. Create VPC
VPC_ID=$(curl -s -X POST http://localhost:8087/api/v1/vpcs \
  -H "Content-Type: application/json" \
  -d '{
    "name": "app-vpc",
    "org_id": "org-123",
    "project_id": "proj-456",
    "cidr_block": "10.100.0.0/16"
  }' | jq -r '.data.id')

# 2. Create Subnet
SUBNET_ID=$(curl -s -X POST http://localhost:8087/api/v1/subnets \
  -H "Content-Type: application/json" \
  -d "{
    \"name\": \"app-subnet\",
    \"vpc_id\": \"$VPC_ID\",
    \"cidr_block\": \"10.100.1.0/24\",
    \"gateway_ip\": \"10.100.1.1\"
  }" | jq -r '.data.id')

# 3. Reserve Credits
RSV_ID=$(curl -s -X POST http://localhost:8086/api/v1/reservations \
  -H "Content-Type: application/json" \
  -d '{
    "project_id": "proj-456",
    "amount": 5000,
    "resource_type": "vm",
    "ttl_seconds": 3600
  }' | jq -r '.data.id')

# 4. Create VM
VM_ID=$(curl -s -X POST http://localhost:8084/api/v1/vms \
  -H "Content-Type: application/json" \
  -d '{
    "name": "app-server",
    "org_id": "org-123",
    "project_id": "proj-456",
    "vcpus": 4,
    "memory_mib": 8192,
    "hypervisor": "kvm"
  }' | jq -r '.data.id')

# 5. Start VM
curl -X POST "http://localhost:8084/api/v1/vms/$VM_ID/start?org_id=org-123&project_id=proj-456"

# 6. Commit Reservation
curl -X POST "http://localhost:8086/api/v1/reservations/$RSV_ID/commit" \
  -H "Content-Type: application/json" \
  -d "{
    \"actual_amount\": 4500,
    \"resource_id\": \"$VM_ID\"
  }"

echo "VM deployed: $VM_ID in VPC: $VPC_ID, Subnet: $SUBNET_ID"
```

### Example 2: Deploy Kubernetes Pod with Service

```bash
# 1. Create Pod
curl -X POST http://localhost:8085/api/v1/pods \
  -H "Content-Type: application/json" \
  -d '{
    "name": "nginx-app",
    "namespace": "production",
    "image": "nginx:1.21"
  }'

# 2. Create Service
curl -X POST http://localhost:8085/api/v1/services \
  -H "Content-Type: application/json" \
  -d '{
    "name": "nginx-service",
    "namespace": "production",
    "service_type": "ClusterIP",
    "port": 80,
    "target_port": 80,
    "selector": {"app": "nginx"}
  }'

# 3. Verify Pod Status
curl "http://localhost:8085/api/v1/pods?namespace=production" | jq '.data.pods[] | select(.name=="nginx-app")'
```

### Example 3: User Authentication Flow

```bash
# 1. Create User
curl -X POST http://localhost:8083/api/v1/users \
  -H "Content-Type: application/json" \
  -d '{
    "id": "user-charlie",
    "name": "Charlie Brown",
    "email": "charlie@example.com",
    "type": "user"
  }'

# 2. Issue Token
TOKEN=$(curl -s -X POST http://localhost:8083/api/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "principal_id": "user-charlie",
    "scope_id": "project-prod",
    "ttl_seconds": 7200
  }' | jq -r '.data.token')

# 3. Verify Token
curl -X POST http://localhost:8083/api/v1/auth/verify \
  -H "Content-Type: application/json" \
  -d "{\"token\": \"$TOKEN\"}"

# 4. Use Token for API Call
curl -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8084/api/v1/vms?org_id=org-123&project_id=project-prod"
```

---

## Debugging Tips

### Check All Services Health
```bash
#!/bin/bash
services=(
  "ChainFire:8081"
  "FlareDB:8082"
  "IAM:8083"
  "PlasmaVMC:8084"
  "k8shost:8085"
  "CreditService:8086"
  "PrismNET:8087"
)

for svc in "${services[@]}"; do
  name="${svc%%:*}"
  port="${svc##*:}"
  echo -n "$name ($port): "
  curl -s http://localhost:$port/health | jq -r '.data.status // "ERROR"'
done
```

### Verbose curl for Debugging
```bash
# Show request/response headers
curl -v http://localhost:8081/health

# Show timing information
curl -w "@-" -o /dev/null -s http://localhost:8081/health <<'EOF'
time_namelookup:  %{time_namelookup}\n
time_connect:  %{time_connect}\n
time_total:  %{time_total}\n
EOF
```

### Pretty-print JSON Responses
```bash
# Install jq if not available
# Ubuntu/Debian: sudo apt-get install jq
# macOS: brew install jq

curl http://localhost:8087/api/v1/vpcs | jq '.'
```

---

## Migration from gRPC

If you have existing gRPC client code, here's how to migrate:

### gRPC (Before)
```rust
use chainfire_client::ChainFireClient;

let mut client = ChainFireClient::connect("http://localhost:50051").await?;
let response = client.get(tonic::Request::new(GetRequest {
    key: "mykey".to_string(),
})).await?;
println!("Value: {}", response.into_inner().value);
```

### REST (After)
```bash
curl http://localhost:8081/api/v1/kv/mykey | jq -r '.data.value'
```

Or with any HTTP client library:
```python
import requests

response = requests.get('http://localhost:8081/api/v1/kv/mykey')
data = response.json()
print(f"Value: {data['data']['value']}")
```

---

## Error Handling

All services return consistent error responses:

### Common HTTP Status Codes

| Code | Meaning | Example |
|------|---------|---------|
| 200 | OK | Successful GET/POST |
| 201 | Created | Resource created |
| 400 | Bad Request | Invalid JSON or missing required fields |
| 404 | Not Found | Resource doesn't exist |
| 409 | Conflict | Resource already exists or state conflict |
| 500 | Internal Server Error | Service error |
| 503 | Service Unavailable | Service not ready (e.g., Raft not leader) |

### Error Response Example
```bash
curl -X POST http://localhost:8087/api/v1/vpcs \
  -H "Content-Type: application/json" \
  -d '{"name": "invalid"}'
```

**Response (400 Bad Request):**
```json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "cidr_block is required",
    "details": {
      "field": "cidr_block",
      "constraint": "required"
    }
  },
  "meta": {
    "request_id": "req-12345",
    "timestamp": "2025-12-12T08:30:00Z"
  }
}
```

### Handling Errors in Scripts
```bash
#!/bin/bash
response=$(curl -s -w "\n%{http_code}" http://localhost:8084/api/v1/vms/invalid-id)
body=$(echo "$response" | head -n -1)
status=$(echo "$response" | tail -n 1)

if [ "$status" -ne 200 ]; then
  echo "Error: $(echo $body | jq -r '.error.message')"
  exit 1
fi

echo "Success: $body"
```

---

## Performance Considerations

### Connection Reuse
For multiple requests, reuse connections:
```bash
# Single connection for multiple requests
curl -K - <<EOF
url = http://localhost:8081/api/v1/kv/key1
url = http://localhost:8081/api/v1/kv/key2
url = http://localhost:8081/api/v1/kv/key3
EOF
```

### Batch Operations
Where possible, use range queries instead of individual requests:
```bash
# Bad: Multiple individual requests
curl http://localhost:8081/api/v1/kv/user:1
curl http://localhost:8081/api/v1/kv/user:2
curl http://localhost:8081/api/v1/kv/user:3

# Good: Single range query
curl "http://localhost:8081/api/v1/kv?prefix=user:"
```

### Parallel Requests
Use `xargs` or GNU `parallel` for concurrent requests:
```bash
# Parallel health checks
echo -e "8081\n8082\n8083\n8084\n8085\n8086\n8087" | \
  xargs -I {} -P 7 curl -s http://localhost:{}/health
```

---

## OpenAPI / Swagger Specifications

OpenAPI specifications are available for each service (planned):

- `docs/api/openapi/chainfire.yaml`
- `docs/api/openapi/flaredb.yaml`
- `docs/api/openapi/iam.yaml`
- `docs/api/openapi/plasmavmc.yaml`
- `docs/api/openapi/k8shost.yaml`
- `docs/api/openapi/creditservice.yaml`
- `docs/api/openapi/prismnet.yaml`

You can import these into Postman, Insomnia, or generate client SDKs using [openapi-generator](https://github.com/OpenAPITools/openapi-generator).

---

## Postman Collection

A Postman collection with all endpoints and example requests is available:
- `docs/api/postman/photoncloud-rest-api.json` (planned)

Import this into Postman for interactive API exploration and testing.

---

## Related Documentation

- **gRPC APIs:** See individual service `proto/` directories
- **Architecture:** `docs/architecture/ARCHITECTURE.md`
- **REST API Patterns:** `docs/specifications/rest-api-patterns.md`
- **Security:** `docs/security/AUTH.md` (when available)
- **Deployment:** `docs/deployment/` (when available)

---

## Support & Feedback

For questions, issues, or feature requests:
- **Project Repository:** `/home/centra/cloud/`
- **Task Tracking:** `docs/por/` (Plan of Record)
- **Active Task:** T050 REST API Implementation

**Last Updated:** 2025-12-12
**Documentation Version:** 1.0 (MVP-Alpha Phase)
