Files
wifi-densepose/v1/docs/user-guide/api-reference.md
Claude 6ed69a3d48 feat: Complete Rust port of WiFi-DensePose with modular crates
Major changes:
- Organized Python v1 implementation into v1/ subdirectory
- Created Rust workspace with 9 modular crates:
  - wifi-densepose-core: Core types, traits, errors
  - wifi-densepose-signal: CSI processing, phase sanitization, FFT
  - wifi-densepose-nn: Neural network inference (ONNX/Candle/tch)
  - wifi-densepose-api: Axum-based REST/WebSocket API
  - wifi-densepose-db: SQLx database layer
  - wifi-densepose-config: Configuration management
  - wifi-densepose-hardware: Hardware abstraction
  - wifi-densepose-wasm: WebAssembly bindings
  - wifi-densepose-cli: Command-line interface

Documentation:
- ADR-001: Workspace structure
- ADR-002: Signal processing library selection
- ADR-003: Neural network inference strategy
- DDD domain model with bounded contexts

Testing:
- 69 tests passing across all crates
- Signal processing: 45 tests
- Neural networks: 21 tests
- Core: 3 doc tests

Performance targets:
- 10x faster CSI processing (~0.5ms vs ~5ms)
- 5x lower memory usage (~100MB vs ~500MB)
- WASM support for browser deployment
2026-01-13 03:11:16 +00:00

21 KiB

API Reference

Overview

The WiFi-DensePose API provides comprehensive access to pose estimation data, system control, and configuration management through RESTful endpoints and real-time WebSocket connections.

Table of Contents

  1. Authentication
  2. Base URL and Versioning
  3. Pose Data Endpoints
  4. System Control Endpoints
  5. Configuration Endpoints
  6. Analytics Endpoints
  7. WebSocket API
  8. Error Handling
  9. Rate Limiting
  10. Code Examples

Authentication

Bearer Token Authentication

All API endpoints require authentication using JWT Bearer tokens:

Authorization: Bearer <your-jwt-token>

Obtaining a Token

# Get authentication token
curl -X POST http://localhost:8000/api/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "username": "your-username",
    "password": "your-password"
  }'

Response:

{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "expires_in": 86400
}

API Key Authentication

For service-to-service communication:

X-API-Key: <your-api-key>

Base URL and Versioning

  • Base URL: http://localhost:8000/api/v1
  • Current Version: v1
  • Content-Type: application/json

Pose Data Endpoints

Get Latest Pose Data

Retrieve the most recent pose estimation results.

Endpoint: GET /pose/latest

Headers:

Authorization: Bearer <token>

Response:

{
  "timestamp": "2025-01-07T04:46:32.123Z",
  "frame_id": 12345,
  "processing_time_ms": 45,
  "persons": [
    {
      "id": 1,
      "confidence": 0.87,
      "bounding_box": {
        "x": 120,
        "y": 80,
        "width": 200,
        "height": 400
      },
      "keypoints": [
        {
          "name": "nose",
          "x": 220,
          "y": 100,
          "confidence": 0.95,
          "visible": true
        },
        {
          "name": "left_shoulder",
          "x": 200,
          "y": 150,
          "confidence": 0.89,
          "visible": true
        }
      ],
      "dense_pose": {
        "body_parts": [
          {
            "part_id": 1,
            "part_name": "torso",
            "uv_coordinates": [[0.5, 0.3], [0.6, 0.4]],
            "confidence": 0.89
          }
        ]
      },
      "tracking_info": {
        "track_id": "track_001",
        "track_age": 150,
        "velocity": {"x": 0.1, "y": 0.05}
      }
    }
  ],
  "metadata": {
    "environment_id": "room_001",
    "router_count": 3,
    "signal_quality": 0.82,
    "processing_pipeline": "standard"
  }
}

Status Codes:

  • 200 OK: Success
  • 404 Not Found: No pose data available
  • 401 Unauthorized: Authentication required
  • 503 Service Unavailable: System not initialized

Get Historical Pose Data

Retrieve historical pose data with filtering options.

Endpoint: GET /pose/history

Query Parameters:

  • start_time (optional): ISO 8601 timestamp for range start
  • end_time (optional): ISO 8601 timestamp for range end
  • limit (optional): Maximum number of records (default: 100, max: 1000)
  • person_id (optional): Filter by specific person ID
  • confidence_threshold (optional): Minimum confidence score (0.0-1.0)

Example:

curl "http://localhost:8000/api/v1/pose/history?start_time=2025-01-07T00:00:00Z&limit=50&confidence_threshold=0.7" \
  -H "Authorization: Bearer <token>"

Response:

{
  "poses": [
    {
      "timestamp": "2025-01-07T04:46:32.123Z",
      "persons": [...],
      "metadata": {...}
    }
  ],
  "pagination": {
    "total_count": 1500,
    "returned_count": 50,
    "has_more": true,
    "next_cursor": "eyJpZCI6MTIzNDV9"
  }
}

Query Pose Data

Execute complex queries on pose data with aggregation support.

Endpoint: POST /pose/query

Request Body:

{
  "query": {
    "time_range": {
      "start": "2025-01-07T00:00:00Z",
      "end": "2025-01-07T23:59:59Z"
    },
    "filters": {
      "person_count": {"min": 1, "max": 5},
      "confidence": {"min": 0.7},
      "activity": ["walking", "standing"]
    },
    "aggregation": {
      "type": "hourly_summary",
      "metrics": ["person_count", "avg_confidence"]
    }
  }
}

Response:

{
  "results": [
    {
      "timestamp": "2025-01-07T10:00:00Z",
      "person_count": 3,
      "avg_confidence": 0.85,
      "activities": {
        "walking": 0.6,
        "standing": 0.4
      }
    }
  ],
  "query_metadata": {
    "execution_time_ms": 150,
    "total_records_scanned": 10000,
    "cache_hit": false
  }
}

System Control Endpoints

Get System Status

Get comprehensive system health and status information.

Endpoint: GET /system/status

Response:

{
  "status": "running",
  "uptime_seconds": 86400,
  "version": "1.0.0",
  "components": {
    "csi_receiver": {
      "status": "active",
      "data_rate_hz": 25.3,
      "packet_loss_rate": 0.02,
      "last_packet_time": "2025-01-07T04:46:32Z"
    },
    "neural_network": {
      "status": "active",
      "model_loaded": true,
      "inference_time_ms": 45,
      "gpu_utilization": 0.65
    },
    "tracking": {
      "status": "active",
      "active_tracks": 2,
      "track_quality": 0.89
    }
  },
  "hardware": {
    "cpu_usage": 0.45,
    "memory_usage": 0.62,
    "gpu_memory_usage": 0.78,
    "disk_usage": 0.23
  },
  "network": {
    "connected_routers": 3,
    "signal_strength": -45,
    "interference_level": 0.15
  }
}

Start System

Start the pose estimation system with configuration options.

Endpoint: POST /system/start

Request Body:

{
  "configuration": {
    "domain": "healthcare",
    "environment_id": "room_001",
    "calibration_required": true
  }
}

Response:

{
  "status": "starting",
  "estimated_ready_time": "2025-01-07T04:47:00Z",
  "initialization_steps": [
    {
      "step": "hardware_initialization",
      "status": "in_progress",
      "progress": 0.3
    },
    {
      "step": "model_loading",
      "status": "pending",
      "progress": 0.0
    }
  ]
}

Stop System

Gracefully stop the pose estimation system.

Endpoint: POST /system/stop

Request Body:

{
  "force": false,
  "save_state": true
}

Response:

{
  "status": "stopping",
  "estimated_stop_time": "2025-01-07T04:47:30Z",
  "shutdown_steps": [
    {
      "step": "data_pipeline_stop",
      "status": "completed",
      "progress": 1.0
    },
    {
      "step": "model_unloading",
      "status": "in_progress",
      "progress": 0.7
    }
  ]
}

Configuration Endpoints

Get Configuration

Retrieve current system configuration.

Endpoint: GET /config

Response:

{
  "domain": "healthcare",
  "environment": {
    "id": "room_001",
    "name": "Patient Room 1",
    "calibration_timestamp": "2025-01-07T04:00:00Z"
  },
  "detection": {
    "confidence_threshold": 0.7,
    "max_persons": 5,
    "tracking_enabled": true
  },
  "alerts": {
    "fall_detection": {
      "enabled": true,
      "sensitivity": 0.8,
      "notification_delay_seconds": 5
    },
    "inactivity_detection": {
      "enabled": true,
      "threshold_minutes": 30
    }
  },
  "streaming": {
    "restream_enabled": false,
    "websocket_enabled": true,
    "mqtt_enabled": true
  }
}

Update Configuration

Update system configuration with partial updates supported.

Endpoint: PUT /config

Request Body:

{
  "detection": {
    "confidence_threshold": 0.75,
    "max_persons": 3
  },
  "alerts": {
    "fall_detection": {
      "sensitivity": 0.9
    }
  }
}

Response:

{
  "status": "updated",
  "changes_applied": [
    "detection.confidence_threshold",
    "detection.max_persons",
    "alerts.fall_detection.sensitivity"
  ],
  "restart_required": false,
  "validation_warnings": []
}

Analytics Endpoints

Healthcare Analytics

Get healthcare-specific analytics and insights.

Endpoint: GET /analytics/healthcare

Query Parameters:

  • period: Time period (hour, day, week, month)
  • metrics: Comma-separated list of metrics

Example:

curl "http://localhost:8000/api/v1/analytics/healthcare?period=day&metrics=fall_events,activity_summary" \
  -H "Authorization: Bearer <token>"

Response:

{
  "period": "day",
  "date": "2025-01-07",
  "metrics": {
    "fall_events": {
      "count": 2,
      "events": [
        {
          "timestamp": "2025-01-07T14:30:15Z",
          "person_id": 1,
          "severity": "moderate",
          "response_time_seconds": 45,
          "location": {"x": 150, "y": 200}
        }
      ]
    },
    "activity_summary": {
      "walking_minutes": 120,
      "sitting_minutes": 480,
      "lying_minutes": 360,
      "standing_minutes": 180
    },
    "mobility_score": 0.75,
    "sleep_quality": {
      "total_sleep_hours": 7.5,
      "sleep_efficiency": 0.89,
      "restlessness_events": 3
    }
  }
}

Retail Analytics

Get retail-specific analytics and customer insights.

Endpoint: GET /analytics/retail

Response:

{
  "period": "day",
  "date": "2025-01-07",
  "metrics": {
    "traffic": {
      "total_visitors": 245,
      "unique_visitors": 198,
      "peak_hour": "14:00",
      "peak_count": 15,
      "average_dwell_time_minutes": 12.5
    },
    "zones": [
      {
        "zone_id": "entrance",
        "zone_name": "Store Entrance",
        "visitor_count": 245,
        "avg_dwell_time_minutes": 2.1,
        "conversion_rate": 0.85
      },
      {
        "zone_id": "electronics",
        "zone_name": "Electronics Section",
        "visitor_count": 89,
        "avg_dwell_time_minutes": 8.7,
        "conversion_rate": 0.34
      }
    ],
    "conversion_funnel": {
      "entrance": 245,
      "product_interaction": 156,
      "checkout_area": 89,
      "purchase": 67
    },
    "heat_map": {
      "high_traffic_areas": [
        {"zone": "entrance", "intensity": 0.95},
        {"zone": "checkout", "intensity": 0.78}
      ]
    }
  }
}

Security Analytics

Get security-specific analytics and threat assessments.

Endpoint: GET /analytics/security

Response:

{
  "period": "day",
  "date": "2025-01-07",
  "metrics": {
    "intrusion_events": {
      "count": 1,
      "events": [
        {
          "timestamp": "2025-01-07T02:15:30Z",
          "zone": "restricted_area",
          "person_count": 1,
          "threat_level": "medium",
          "response_time_seconds": 120
        }
      ]
    },
    "perimeter_monitoring": {
      "total_detections": 45,
      "authorized_entries": 42,
      "unauthorized_attempts": 3,
      "false_positives": 0
    },
    "crowd_analysis": {
      "max_occupancy": 12,
      "average_occupancy": 3.2,
      "crowd_formation_events": 0
    }
  }
}

WebSocket API

Connection

Connect to the WebSocket endpoint for real-time data streaming.

Endpoint: ws://localhost:8000/ws/pose

Authentication: Include token as query parameter or in headers:

const ws = new WebSocket('ws://localhost:8000/ws/pose?token=<your-jwt-token>');

Connection Establishment

Server Message:

{
  "type": "connection_established",
  "client_id": "client_12345",
  "server_time": "2025-01-07T04:46:32Z",
  "supported_protocols": ["pose_v1", "alerts_v1"]
}

Subscription Management

Subscribe to Pose Updates:

{
  "type": "subscribe",
  "channel": "pose_updates",
  "filters": {
    "min_confidence": 0.7,
    "person_ids": [1, 2, 3],
    "include_keypoints": true,
    "include_dense_pose": false
  }
}

Subscription Confirmation:

{
  "type": "subscription_confirmed",
  "channel": "pose_updates",
  "subscription_id": "sub_67890",
  "filters_applied": {
    "min_confidence": 0.7,
    "person_ids": [1, 2, 3]
  }
}

Real-Time Data Streaming

Pose Update Message:

{
  "type": "pose_update",
  "subscription_id": "sub_67890",
  "timestamp": "2025-01-07T04:46:32.123Z",
  "data": {
    "frame_id": 12345,
    "persons": [...],
    "metadata": {...}
  }
}

System Status Update:

{
  "type": "system_status",
  "timestamp": "2025-01-07T04:46:32Z",
  "status": {
    "processing_fps": 25.3,
    "active_persons": 2,
    "system_health": "good",
    "gpu_utilization": 0.65
  }
}

Alert Streaming

Subscribe to Alerts:

{
  "type": "subscribe",
  "channel": "alerts",
  "filters": {
    "alert_types": ["fall_detection", "intrusion"],
    "severity": ["high", "critical"]
  }
}

Alert Message:

{
  "type": "alert",
  "alert_id": "alert_12345",
  "timestamp": "2025-01-07T04:46:32Z",
  "alert_type": "fall_detection",
  "severity": "high",
  "data": {
    "person_id": 1,
    "location": {"x": 220, "y": 180},
    "confidence": 0.92,
    "video_clip_url": "/clips/fall_12345.mp4"
  },
  "actions_required": ["medical_response", "notification"]
}

Error Handling

Standard Error Response Format

{
  "error": {
    "code": "POSE_DATA_NOT_FOUND",
    "message": "No pose data available for the specified time range",
    "details": {
      "requested_range": {
        "start": "2025-01-07T00:00:00Z",
        "end": "2025-01-07T01:00:00Z"
      },
      "available_range": {
        "start": "2025-01-07T02:00:00Z",
        "end": "2025-01-07T04:46:32Z"
      }
    },
    "timestamp": "2025-01-07T04:46:32Z",
    "request_id": "req_12345"
  }
}

HTTP Status Codes

Success Codes

  • 200 OK: Request successful
  • 201 Created: Resource created successfully
  • 202 Accepted: Request accepted for processing
  • 204 No Content: Request successful, no content returned

Client Error Codes

  • 400 Bad Request: Invalid request format or parameters
  • 401 Unauthorized: Authentication required or invalid
  • 403 Forbidden: Insufficient permissions
  • 404 Not Found: Resource not found
  • 409 Conflict: Resource conflict (e.g., system already running)
  • 422 Unprocessable Entity: Validation errors
  • 429 Too Many Requests: Rate limit exceeded

Server Error Codes

  • 500 Internal Server Error: Unexpected server error
  • 502 Bad Gateway: Upstream service error
  • 503 Service Unavailable: System not ready or overloaded
  • 504 Gateway Timeout: Request timeout

Validation Error Response

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": {
      "field_errors": [
        {
          "field": "confidence_threshold",
          "message": "Value must be between 0.0 and 1.0",
          "received_value": 1.5
        },
        {
          "field": "max_persons",
          "message": "Value must be a positive integer",
          "received_value": -1
        }
      ]
    },
    "timestamp": "2025-01-07T04:46:32Z",
    "request_id": "req_12346"
  }
}

Rate Limiting

Rate Limit Headers

All responses include rate limiting information:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1704686400
X-RateLimit-Window: 3600

Rate Limits by Endpoint Type

  • REST API: 1000 requests per hour per API key
  • WebSocket: 100 connections per IP address
  • Streaming: 10 concurrent streams per account
  • Webhook: 10,000 events per hour per endpoint

Rate Limit Exceeded Response

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Try again later.",
    "details": {
      "limit": 1000,
      "window_seconds": 3600,
      "reset_time": "2025-01-07T05:46:32Z"
    },
    "timestamp": "2025-01-07T04:46:32Z",
    "request_id": "req_12347"
  }
}

Code Examples

Python Example

import requests
import json
from datetime import datetime, timedelta

class WiFiDensePoseClient:
    def __init__(self, base_url, token):
        self.base_url = base_url
        self.headers = {
            'Authorization': f'Bearer {token}',
            'Content-Type': 'application/json'
        }
    
    def get_latest_pose(self):
        """Get the latest pose data."""
        response = requests.get(
            f'{self.base_url}/pose/latest',
            headers=self.headers
        )
        response.raise_for_status()
        return response.json()
    
    def get_historical_poses(self, start_time=None, end_time=None, limit=100):
        """Get historical pose data."""
        params = {'limit': limit}
        if start_time:
            params['start_time'] = start_time.isoformat()
        if end_time:
            params['end_time'] = end_time.isoformat()
        
        response = requests.get(
            f'{self.base_url}/pose/history',
            headers=self.headers,
            params=params
        )
        response.raise_for_status()
        return response.json()
    
    def start_system(self, domain='general', environment_id='default'):
        """Start the pose estimation system."""
        data = {
            'configuration': {
                'domain': domain,
                'environment_id': environment_id,
                'calibration_required': True
            }
        }
        response = requests.post(
            f'{self.base_url}/system/start',
            headers=self.headers,
            json=data
        )
        response.raise_for_status()
        return response.json()

# Usage example
client = WiFiDensePoseClient('http://localhost:8000/api/v1', 'your-token')

# Get latest pose data
latest = client.get_latest_pose()
print(f"Found {len(latest['persons'])} persons")

# Get historical data for the last hour
end_time = datetime.now()
start_time = end_time - timedelta(hours=1)
history = client.get_historical_poses(start_time, end_time)
print(f"Retrieved {len(history['poses'])} historical records")

JavaScript Example

class WiFiDensePoseClient {
    constructor(baseUrl, token) {
        this.baseUrl = baseUrl;
        this.headers = {
            'Authorization': `Bearer ${token}`,
            'Content-Type': 'application/json'
        };
    }

    async getLatestPose() {
        const response = await fetch(`${this.baseUrl}/pose/latest`, {
            headers: this.headers
        });
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        return await response.json();
    }

    async updateConfiguration(config) {
        const response = await fetch(`${this.baseUrl}/config`, {
            method: 'PUT',
            headers: this.headers,
            body: JSON.stringify(config)
        });
        
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        
        return await response.json();
    }

    connectWebSocket() {
        const ws = new WebSocket(`ws://localhost:8000/ws/pose?token=${this.token}`);
        
        ws.onopen = () => {
            console.log('WebSocket connected');
            // Subscribe to pose updates
            ws.send(JSON.stringify({
                type: 'subscribe',
                channel: 'pose_updates',
                filters: {
                    min_confidence: 0.7
                }
            }));
        };
        
        ws.onmessage = (event) => {
            const data = JSON.parse(event.data);
            console.log('Received:', data);
        };
        
        ws.onerror = (error) => {
            console.error('WebSocket error:', error);
        };
        
        return ws;
    }
}

// Usage example
const client = new WiFiDensePoseClient('http://localhost:8000/api/v1', 'your-token');

// Get latest pose data
client.getLatestPose()
    .then(data => console.log('Latest pose:', data))
    .catch(error => console.error('Error:', error));

// Connect to WebSocket for real-time updates
const ws = client.connectWebSocket();

cURL Examples

# Get authentication token
curl -X POST http://localhost:8000/api/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "password"}'

# Get latest pose data
curl http://localhost:8000/api/v1/pose/latest \
  -H "Authorization: Bearer <token>"

# Start system
curl -X POST http://localhost:8000/api/v1/system/start \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "configuration": {
      "domain": "healthcare",
      "environment_id": "room_001"
    }
  }'

# Update configuration
curl -X PUT http://localhost:8000/api/v1/config \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "detection": {
      "confidence_threshold": 0.8
    }
  }'

# Get healthcare analytics
curl "http://localhost:8000/api/v1/analytics/healthcare?period=day" \
  -H "Authorization: Bearer <token>"

For more detailed information, see: