PublicRisk.ai

API Reference

Complete API documentation for PublicRisk.ai Modal backend services

API Reference

PublicRisk.ai provides a comprehensive REST API hosted on Modal Cloud Platform. All services are serverless, auto-scaling, and feature Redis caching for optimal performance.

Base URL: https://publicrisk--publicrisk-consolidated-backend-serve.modal.run

All endpoints require JWT authentication unless specified. Include the token in the Authorization header:

Authorization: Bearer <your-jwt-token>

Authentication & User Management

POST /api/auth/login

Authenticate user and obtain JWT token.

Request Body:

{
  "email": "user@example.com",
  "password": "secure_password"
}

Response:

{
  "success": true,
  "access_token": "eyJhbGciOiJIUzI1NiIs...",
  "token_type": "bearer",
  "expires_in": 3600,
  "user": {
    "id": "user-123",
    "email": "user@example.com",
    "role": "User",
    "two_factor_enabled": true
  }
}

Status Codes:

  • 200 - Success
  • 401 - Invalid credentials
  • 403 - Account locked

POST /api/auth/verify-2fa

Verify two-factor authentication code during login.

Request Body:

{
  "user_id": "user-123",
  "code": "123456",
  "remember_device": true
}

Response:

{
  "success": true,
  "verified": true,
  "session_token": "eyJhbGciOiJIUzI1NiIs..."
}

Status Codes:

  • 200 - Code verified
  • 400 - Invalid code
  • 429 - Too many attempts

POST /api/auth/2fa/setup

Generate QR code for 2FA setup (requires authentication).

Response:

{
  "success": true,
  "qr_code": "data:image/png;base64,iVBORw0KGgoAAAANS...",
  "secret": "JBSWY3DPEHPK3PXP",
  "recovery_codes": [
    "ABC123-DEF456",
    "GHI789-JKL012"
  ]
}

POST /api/auth/2fa/enable

Enable 2FA after verifying setup code.

Request Body:

{
  "code": "123456"
}

Response:

{
  "success": true,
  "enabled": true,
  "recovery_codes": ["ABC123-DEF456", "GHI789-JKL012"]
}

GET /api/auth/2fa/status

Check current 2FA status for authenticated user.

Response:

{
  "enabled": true,
  "verification_interval": "weekly",
  "last_verified": "2025-12-01T10:00:00Z"
}

POST /api/auth/change-password

Change user password (requires authentication).

Request Body:

{
  "old_password": "current_password",
  "new_password": "new_secure_password"
}

Response:

{
  "success": true,
  "message": "Password changed successfully"
}

Admin & Organization Management

GET /api/admin/users

List all users (SuperAdmin/Admin only).

Query Parameters:

  • role (optional): Filter by role (User, Admin, SuperAdmin)
  • status (optional): Filter by status (active, inactive, suspended)
  • page (optional): Page number (default: 1)
  • limit (optional): Results per page (default: 50)

Response:

{
  "success": true,
  "users": [
    {
      "id": "user-123",
      "name": "John Doe",
      "email": "john@example.com",
      "role": "User",
      "status": "active",
      "two_factor_enabled": true,
      "client_id": "org-456",
      "last_login": "2025-12-01T10:00:00Z",
      "created_at": "2025-01-15T08:30:00Z"
    }
  ],
  "total": 150,
  "page": 1,
  "pages": 3
}

POST /api/admin/users

Create new user (Admin only).

Request Body:

{
  "name": "Jane Smith",
  "email": "jane@example.com",
  "password": "secure_password",
  "role": "User",
  "client_id": "org-456",
  "permissions": ["read", "write"],
  "timezone": "America/Los_Angeles"
}

Response:

{
  "success": true,
  "user": {
    "id": "user-789",
    "email": "jane@example.com",
    "created_at": "2025-12-01T11:00:00Z"
  }
}

POST /api/admin/users/{user_id}/2fa

Manage user 2FA settings (Admin only).

Path Parameters:

  • user_id: Target user ID

Request Body:

{
  "action": "require" // or "reset"
}

Response:

{
  "success": true,
  "message": "2FA required for user",
  "user_id": "user-123",
  "two_factor_enabled": true
}

GET /api/admin/organizations

List all client organizations (SuperAdmin only).

Response:

{
  "success": true,
  "organizations": [
    {
      "id": "org-456",
      "name": "Acme Corporation",
      "contact_email": "admin@acme.com",
      "max_users": 100,
      "current_users": 75,
      "subscription_tier": "enterprise",
      "status": "active",
      "features": ["hazus", "storm", "2fa"],
      "created_at": "2024-06-15T08:00:00Z"
    }
  ],
  "total": 25
}

GET /api/admin/audit-logs

Retrieve system audit logs (Admin only).

Query Parameters:

  • user_id (optional): Filter by user
  • action (optional): Filter by action type
  • start_date (optional): ISO 8601 date
  • end_date (optional): ISO 8601 date
  • limit (optional): Results per page (default: 100)

Response:

{
  "success": true,
  "logs": [
    {
      "id": "log-123",
      "timestamp": "2025-12-01T10:30:00Z",
      "user_id": "user-123",
      "user_name": "John Doe",
      "action": "document_upload",
      "resource": "doc-456",
      "status": "success",
      "ip_address": "192.168.1.1",
      "details": "Uploaded policy.pdf to RAG store"
    }
  ],
  "total": 5000,
  "page": 1
}

HAZUS Disaster Risk Assessment

For complete HAZUS documentation, see HAZUS Detailed Guide.

GET /health

Check HAZUS service health.

Base URL: https://publicrisk--publicrisk-hazard-service-*.modal.run

Response:

{
  "status": "healthy",
  "service": "hazus-disaster-risk",
  "version": "1.0.0",
  "cache_enabled": true,
  "data_sources": {
    "fema_nfhl": "active",
    "usgs_nshm": "active",
    "nifc_wildfire": "active"
  }
}

GET /assess-property

Comprehensive property risk assessment.

Query Parameters:

  • lat (required): Latitude (-90 to 90)
  • lng (required): Longitude (-180 to 180)
  • property_value (required): Property value in USD
  • year_built (optional): Construction year (default: 2000)

Response:

{
  "overall_risk": {
    "score": 7.2,
    "level": "High",
    "annual_expected_loss": 12500
  },
  "flood": {
    "zone": "AE",
    "base_flood_elevation": 12.5,
    "annual_probability": 0.01,
    "estimated_damage": 85000,
    "damage_ratio": 0.25
  },
  "earthquake": {
    "pga": 0.35,
    "magnitude_estimate": 6.5,
    "annual_probability": 0.002,
    "estimated_damage": 150000,
    "damage_ratio": 0.45
  },
  "wildfire": {
    "ignition_probability": 0.15,
    "intensity_level": "moderate",
    "annual_probability": 0.08,
    "estimated_damage": 50000
  },
  "mitigation_recommendations": [
    {
      "hazard": "flood",
      "action": "Elevate utilities above BFE",
      "cost_estimate": 5000,
      "risk_reduction": 0.4
    }
  ],
  "location": {
    "latitude": 34.0522,
    "longitude": -118.2437,
    "county": "Los Angeles County",
    "state": "CA"
  }
}

Cold Start: First request may take 30-60 seconds. Subsequent requests: less than 3 seconds.


GET /realtime-all

Get real-time hazard data for map markers.

Query Parameters:

  • lat (required): Latitude
  • lng (required): Longitude

Response:

{
  "flood": {
    "zone": "X",
    "risk_level": "minimal"
  },
  "earthquake": {
    "pga": 0.15,
    "risk_level": "moderate"
  },
  "wildfire": {
    "active_fires_nearby": 2,
    "nearest_fire_distance_km": 25.3,
    "air_quality_index": 85
  }
}

GET /flood-risk

Detailed flood risk analysis.

Query Parameters:

  • lat, lng: Coordinates
  • property_value: Property value

Response:

{
  "zone": "AE",
  "base_flood_elevation": 12.5,
  "depth_damage_curve": [
    {"depth_ft": 0, "damage_ratio": 0.0},
    {"depth_ft": 2, "damage_ratio": 0.15},
    {"depth_ft": 4, "damage_ratio": 0.35}
  ],
  "estimated_damage": 85000,
  "annual_probability": 0.01
}

GET /earthquake-risk

Detailed earthquake risk analysis.

Query Parameters:

  • lat, lng: Coordinates
  • property_value: Property value
  • year_built: Construction year

Response:

{
  "pga": 0.35,
  "magnitude_estimate": 6.5,
  "spectral_acceleration": {
    "sa_0_2s": 0.85,
    "sa_1_0s": 0.40
  },
  "building_vulnerability": {
    "construction_type": "wood_frame",
    "expected_damage_ratio": 0.45
  },
  "estimated_damage": 150000
}

GET /wildfire-risk

Detailed wildfire risk analysis.

Query Parameters:

  • lat, lng: Coordinates
  • property_value: Property value

Response:

{
  "ignition_probability": 0.15,
  "intensity_level": "moderate",
  "fuel_load": "high",
  "topography_factor": 1.3,
  "wind_exposure": "moderate",
  "active_fires": [
    {
      "name": "Creek Fire",
      "distance_km": 25.3,
      "containment": 45,
      "acres": 12500
    }
  ],
  "estimated_damage": 50000
}

STORM Document Generation

For complete STORM documentation, see STORM Generator Guide.

POST /api/dspy/storm/generate

Generate structured report using STORM methodology.

Request Body:

{
  "topic": "Wildfire Risk Assessment for Riverside County",
  "template": "risk_assessment",
  "parameters": {
    "research_depth": "comprehensive",
    "document_length": "detailed",
    "citation_style": "APA",
    "model": "moonshot-kimi-k2-thinking-general",
    "use_rag": true,
    "rag_stores": ["hazus_docs", "policy_library"]
  },
  "context": {
    "location": "Riverside County, CA",
    "property_value": 500000,
    "assessment_date": "2025-12-01"
  }
}

Response:

{
  "job_id": "storm-abc123",
  "status": "processing",
  "estimated_time_seconds": 180,
  "stages": [
    {
      "name": "topic_expansion",
      "status": "completed",
      "progress": 100
    },
    {
      "name": "perspective_generation",
      "status": "in_progress",
      "progress": 60
    }
  ]
}

GET /api/dspy/storm/status/{job_id}

Check STORM generation job status.

Path Parameters:

  • job_id: Job ID from generation request

Response:

{
  "job_id": "storm-abc123",
  "status": "completed",
  "progress": 100,
  "result": {
    "title": "Wildfire Risk Assessment for Riverside County",
    "sections": [
      {
        "heading": "Executive Summary",
        "content": "This assessment evaluates...",
        "citations": ["Source 1", "Source 2"]
      }
    ],
    "metadata": {
      "generation_time_seconds": 165,
      "total_words": 4500,
      "citations_count": 23,
      "rag_sources_used": 15
    }
  }
}

POST /api/dspy/query

DSPy-optimized query processing.

Request Body:

{
  "query": "What are the seismic hazards in San Francisco?",
  "use_rag": true,
  "max_tokens": 1000,
  "temperature": 0.7
}

Response:

{
  "success": true,
  "response": "San Francisco faces significant seismic hazards...",
  "sources": [
    {
      "title": "USGS Bay Area Seismic Report",
      "score": 0.92,
      "excerpt": "The San Andreas Fault..."
    }
  ],
  "model": "moonshot-kimi-k2-thinking-general",
  "tokens_used": 850
}

RAG Management

POST /api/simple-rag/upload

Upload documents to RAG vector store.

Request Body:

{
  "files": [
    {
      "name": "policy.pdf",
      "type": "application/pdf",
      "size": 1024000,
      "content": "base64_encoded_content_here"
    }
  ],
  "settings": {
    "rag_store": "policy_library",
    "chunk_size": 1000,
    "chunk_overlap": 200,
    "embedding_model": "nomic-embed-text",
    "auto_process": true
  },
  "metadata": {
    "category": "insurance_policy",
    "tags": ["commercial", "liability"],
    "uploaded_by": "user@example.com"
  }
}

Response:

{
  "success": true,
  "documents": [
    {
      "document_id": "doc-123",
      "filename": "policy.pdf",
      "status": "processing",
      "chunks_created": 45,
      "processing_time_ms": 2500
    }
  ],
  "total_uploaded": 1
}

GET /api/simple-rag/documents

List documents in RAG store.

Query Parameters:

  • rag_store (optional): Filter by store name
  • category (optional): Filter by category
  • limit (optional): Results per page (default: 50)

Response:

{
  "success": true,
  "documents": [
    {
      "id": "doc-123",
      "filename": "policy.pdf",
      "category": "insurance_policy",
      "tags": ["commercial", "liability"],
      "chunk_count": 45,
      "uploaded_at": "2025-12-01T10:00:00Z",
      "size_bytes": 1024000,
      "status": "active"
    }
  ],
  "total": 150
}

GET /api/simple-rag/stats

Get RAG system statistics.

Response:

{
  "success": true,
  "stores": [
    {
      "name": "policy_library",
      "document_count": 450,
      "total_chunks": 12500,
      "storage_used_mb": 850,
      "last_updated": "2025-12-01T09:30:00Z"
    }
  ],
  "total_documents": 450,
  "total_chunks": 12500,
  "embedding_model": "nomic-embed-text",
  "vector_dimensions": 768
}

POST /api/simple-rag/search

Search RAG vector store.

Request Body:

{
  "query": "What is the cyber liability coverage limit?",
  "rag_store": "policy_library",
  "limit": 10,
  "similarity_threshold": 0.7,
  "filters": {
    "category": "insurance_policy",
    "tags": ["cyber"]
  }
}

Response:

{
  "success": true,
  "results": [
    {
      "id": "chunk-456",
      "content": "Cyber liability coverage provides up to $5M...",
      "score": 0.92,
      "document_id": "doc-123",
      "document_name": "cyber_policy.pdf",
      "metadata": {
        "page": 12,
        "section": "Coverage Limits"
      }
    }
  ],
  "total_results": 8,
  "query_time_ms": 45
}

DELETE /api/simple-rag/documents/{document_id}

Delete document from RAG store.

Path Parameters:

  • document_id: Document ID to delete

Response:

{
  "success": true,
  "message": "Document deleted successfully",
  "chunks_removed": 45
}

Query Explorer (Multi-Engine Analysis)

POST /api/query-explorer/analyze

Analyze query through multi-engine reasoning pipeline.

Request Body:

{
  "query": "What is the flood risk in Miami, FL?",
  "context": {
    "latitude": 25.7617,
    "longitude": -80.1918
  },
  "return_intermediate": true,
  "async_mode": false
}

Response:

{
  "success": true,
  "job_id": "qe-xyz789",
  "classification": {
    "query_type": "disaster_modeling",
    "hazards": ["flood"],
    "complexity": "standard"
  },
  "perspectives": [
    {
      "name": "HAZUS Analysis",
      "confidence": 0.95,
      "data": {
        "flood_zone": "AE",
        "annual_probability": 0.01
      }
    }
  ],
  "final_answer": "Miami faces significant flood risk...",
  "processing_time_ms": 3500
}

GET /api/query-explorer/status/{job_id}

Check status of async analysis job.

Path Parameters:

  • job_id: Job ID from analyze request

Response:

{
  "job_id": "qe-xyz789",
  "status": "completed",
  "progress": 100,
  "result": {
    "final_answer": "Miami faces significant flood risk...",
    "perspectives_count": 3
  }
}

GET /api/query-explorer/jobs

List recent analysis jobs.

Query Parameters:

  • status (optional): Filter by status (pending, processing, completed, failed)
  • limit (optional): Results per page (default: 20)

Response:

{
  "success": true,
  "jobs": [
    {
      "job_id": "qe-xyz789",
      "query": "What is the flood risk in Miami, FL?",
      "status": "completed",
      "created_at": "2025-12-01T10:00:00Z",
      "completed_at": "2025-12-01T10:00:05Z"
    }
  ],
  "total": 50
}

DELETE /api/query-explorer/jobs/{job_id}

Clean up completed job.

Response:

{
  "success": true,
  "message": "Job deleted successfully"
}

SIPMath SLURP (Correlated Risk Analysis)

POST /api/sipmath/create-slurp

Create correlated SIP distributions (SLURP).

Request Body:

{
  "hazards": [
    {
      "type": "earthquake",
      "location": {"lat": 34.0522, "lng": -118.2437},
      "params": {"property_value": 500000}
    },
    {
      "type": "wildfire",
      "location": {"lat": 34.0522, "lng": -118.2437},
      "params": {"property_value": 500000}
    }
  ],
  "correlation_matrix": {
    "earthquake": {"wildfire": 0.4},
    "wildfire": {"earthquake": 0.4}
  },
  "num_trials": 10000
}

Response:

{
  "status": "success",
  "name": "Multi_Hazard_SLURP",
  "coherent": true,
  "count": 2,
  "sips": [
    {
      "name": "earthquake_loss",
      "type": "lognormal",
      "mean": 125000,
      "std": 75000,
      "trials": [...]
    },
    {
      "name": "wildfire_loss",
      "type": "lognormal",
      "mean": 85000,
      "std": 45000,
      "trials": [...]
    }
  ],
  "correlation_matrix_target": {
    "earthquake": {"wildfire": 0.4}
  },
  "correlation_matrix_realized": {
    "earthquake": {"wildfire": 0.398}
  }
}

Use Case: Model realistic multi-hazard scenarios where risks are correlated (e.g., earthquake triggering wildfire).


POST /api/sipmath/aggregate-slurp

Aggregate correlated SIPs into single distribution.

Request Body:

{
  "slurp": {
    "sips": [...],
    "correlation_matrix": {...}
  },
  "aggregation_type": "sum",
  "weights": null
}

Response:

{
  "status": "success",
  "aggregated_sip": {
    "name": "total_loss",
    "type": "empirical",
    "mean": 210000,
    "std": 95000,
    "percentiles": {
      "p10": 75000,
      "p50": 185000,
      "p90": 350000
    },
    "trials": [...]
  },
  "coherent_aggregation": true,
  "component_contributions": {
    "earthquake": 0.60,
    "wildfire": 0.40
  }
}

POST /api/sipmath/hazus-to-sip

Convert HAZUS risk assessment to SIPMath distribution.

Request Body:

{
  "hazus_data": {
    "flood": {
      "annual_probability": 0.01,
      "estimated_damage": 85000
    },
    "earthquake": {
      "annual_probability": 0.002,
      "estimated_damage": 150000
    }
  },
  "num_trials": 10000
}

Response:

{
  "status": "success",
  "sips": [
    {
      "name": "flood_annual_loss",
      "type": "bernoulli_scaled",
      "probability": 0.01,
      "loss_given_event": 85000,
      "mean": 850,
      "trials": [...]
    }
  ]
}

Cybersecurity (CISA KEV Integration)

GET /api/cyber/kev

Get CISA Known Exploited Vulnerabilities.

Query Parameters:

  • vendor (optional): Filter by vendor name
  • product (optional): Filter by product name
  • days (optional): Recent vulnerabilities (e.g., 30 days)
  • ransomware_only (optional): Boolean flag

Response:

{
  "success": true,
  "vulnerabilities": [
    {
      "cve_id": "CVE-2024-12345",
      "vendor": "Microsoft",
      "product": "Windows Server",
      "vulnerability_name": "Remote Code Execution",
      "date_added": "2025-11-15",
      "due_date": "2025-12-15",
      "ransomware_use": true,
      "notes": "Actively exploited in the wild"
    }
  ],
  "total": 1200,
  "last_updated": "2025-12-01T06:00:00Z"
}

GET /api/cyber/infrastructure-threats

Get threats by critical infrastructure sector.

Response:

{
  "success": true,
  "sectors": [
    {
      "name": "Energy",
      "threat_count": 45,
      "high_severity": 12,
      "vulnerabilities": [...]
    },
    {
      "name": "Water",
      "threat_count": 23,
      "high_severity": 5,
      "vulnerabilities": [...]
    }
  ]
}

GET /api/cyber/kev/cve/{cve_id}

Get details for specific CVE.

Path Parameters:

  • cve_id: CVE identifier (e.g., CVE-2024-12345)

Response:

{
  "success": true,
  "cve": {
    "cve_id": "CVE-2024-12345",
    "vendor": "Microsoft",
    "product": "Windows Server",
    "vulnerability_name": "Remote Code Execution",
    "description": "An attacker can execute arbitrary code...",
    "cvss_score": 9.8,
    "date_added": "2025-11-15",
    "due_date": "2025-12-15",
    "ransomware_use": true,
    "mitigation": "Apply security patch KB5012345"
  }
}

Data Visualization

POST /api/dspy/visualization-pipeline

Generate dynamic visualizations from query.

Request Body:

{
  "query": "Show flood damage by building type in Miami",
  "data_context": {
    "location": "Miami, FL",
    "hazard": "flood"
  },
  "chart_preferences": {
    "type": "auto",
    "color_scheme": "blue"
  }
}

Response:

{
  "success": true,
  "visualization": {
    "type": "bar_chart",
    "title": "Flood Damage by Building Type - Miami, FL",
    "data": [
      {"category": "Residential", "value": 125000},
      {"category": "Commercial", "value": 350000}
    ],
    "config": {
      "x_axis": "Building Type",
      "y_axis": "Estimated Damage ($)",
      "color": "#0088FE"
    }
  }
}

POST /api/dspy/categorize-query

Categorize query for visualization routing.

Request Body:

{
  "query": "Show earthquake risk distribution"
}

Response:

{
  "category": "spatial_distribution",
  "recommended_chart": "map",
  "confidence": 0.92
}

PEFT Adapters (Domain Specialization)

35 Production Domains: All adapters trained on Llama 3.1 70B with LoRA, deployed on Modal Cloud with GPU inference.

GET /api/peft/adapters

List available PEFT adapters (35 domains).

Query Parameters:

  • domain (optional): Filter by specific domain
  • status (optional): Filter by deployment status

Response:

{
  "status": "success",
  "count": 35,
  "trained_domains": [
    "academic_research", "CA_education_code", "CA_government_code",
    "climate", "cybersecurity", "education", "emergency_management",
    "environmental", "financial", "geopolitical", "healthcare",
    "hr-employment", "infrastructure", "insurance", "insurance_exposures",
    "law_enforcement", "legal", "liability", "municipal", "municipal_codes",
    "natural_disasters", "nepa", "operational", "procurement", "property",
    "public_education", "public_financing", "regulatory", "reputational",
    "risk-analysis", "school-risk", "supply_chain", "technology",
    "utilities", "workers-comp"
  ],
  "adapters": [
    {
      "adapter_id": "cybersecurity_v20251206_120000",
      "domain": "cybersecurity",
      "version": "v1.0",
      "deployment_status": "active",
      "training_samples": 1800,
      "accuracy": 0.94,
      "size_mb": 45.2,
      "base_model": "meta-llama/Llama-3.1-70B-Instruct",
      "lora_config": {
        "rank": 16,
        "alpha": 32,
        "learning_rate": 0.0002
      },
      "created_at": "2025-12-06T12:00:00Z",
      "query_explorer_enabled": true
    },
    {
      "adapter_id": "public_education_v20251205_093000",
      "domain": "public_education",
      "version": "v1.0",
      "deployment_status": "testing",
      "training_samples": 2000,
      "size_mb": 48.7,
      "created_at": "2025-12-05T09:30:00Z"
    }
  ]
}

POST /api/peft/inference

Run inference with domain-specific adapter.

Request Body:

{
  "query": "What cybersecurity controls are required for storing student data?",
  "domain": "cybersecurity",
  "adapter_version": "v1.0",
  "max_new_tokens": 512,
  "temperature": 0.7
}

Response:

{
  "status": "success",
  "query": "What cybersecurity controls are required for storing student data?",
  "domain": "cybersecurity",
  "response": "For storing student data, FERPA requires:\n\n1. **Access Controls**: Role-based permissions limiting access to authorized personnel only\n2. **Encryption**: AES-256 encryption at rest and TLS 1.3 in transit\n3. **Audit Logging**: Track all access and modifications with timestamp and user ID\n4. **Multi-Factor Authentication**: Required for any remote access\n5. **Data Classification**: Mark all student records as 'Confidential'\n\nAdditional state requirements may apply depending on jurisdiction.",
  "metadata": {
    "adapter_version": "v1.0",
    "adapter_loaded": true,
    "inference_time_ms": 1850,
    "tokens_generated": 147
  }
}

POST /api/peft/train

SuperAdmin Only - Train a new PEFT adapter.

Request Body:

{
  "domain": "cybersecurity",
  "training_data_size": 1500,
  "epochs": 10,
  "lora_rank": 16,
  "lora_alpha": 32,
  "learning_rate": 0.0002
}

Response:

{
  "status": "success",
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "adapter_id": "cybersecurity_v20251206_143022",
  "domain": "cybersecurity",
  "estimated_time_minutes": 60,
  "estimated_cost_usd": 1.50,
  "message": "Training job queued. Check status with /api/peft/training/status/{job_id}"
}

GET /api/peft/training/status/{job_id}

Check training job status (async training with real-time updates).

Path Parameters:

  • job_id: Training job UUID

Response (In Progress):

{
  "status": "success",
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "training_status": "training",
  "progress_percent": 45,
  "current_epoch": 5,
  "total_epochs": 10,
  "elapsed_time_seconds": 1800,
  "estimated_remaining_minutes": 20
}

Response (Completed):

{
  "status": "success",
  "training_status": "completed",
  "progress_percent": 100,
  "training_loss": 0.42,
  "adapter_id": "cybersecurity_v20251206_143022",
  "adapter_size_mb": 45.2,
  "training_time_seconds": 3600
}

POST /api/peft/test

SuperAdmin Only - Run A/B test comparing base model vs adapter.

Request Body:

{
  "adapter_id": "cybersecurity_v20251206_143022",
  "domain": "cybersecurity",
  "test_queries": [
    "What is a SQL injection attack?",
    "How do I prevent XSS vulnerabilities?",
    "What are the requirements for PCI DSS compliance?",
    "How should passwords be stored securely?",
    "What is zero trust architecture?"
  ]
}

Response:

{
  "status": "success",
  "adapter_id": "cybersecurity_v20251206_143022",
  "domain": "cybersecurity",
  "average_improvement": 0.23,
  "recommendation": "approve",
  "test_results": [
    {
      "query": "What is a SQL injection attack?",
      "base_response": {
        "answer": "SQL injection is a code injection technique...",
        "confidence": 0.75,
        "processing_time_ms": 1200
      },
      "adapter_response": {
        "answer": "SQL injection (SQLi) is a critical web security vulnerability (OWASP Top 10) that allows attackers to...",
        "confidence": 0.92,
        "processing_time_ms": 1100
      },
      "accuracy_improvement": 0.17,
      "confidence_improvement": 0.17
    }
  ],
  "metadata": {
    "tested_at": "2025-12-06T15:30:00Z",
    "num_queries": 5
  }
}

POST /api/peft/approve

SuperAdmin Only - Approve adapter for production deployment.

Request Body:

{
  "domain": "cybersecurity",
  "approved_by": "admin@example.com",
  "notes": "94% accuracy on test queries, 17% improvement over base model",
  "test_results": { /* A/B test results */ }
}

Response:

{
  "status": "success",
  "message": "Adapter approved for domain: cybersecurity",
  "adapter_id": "cybersecurity_v20251206_143022",
  "deployment_status": "approved"
}

Error Responses

All endpoints follow consistent error formatting:

{
  "success": false,
  "error": {
    "code": "AUTHENTICATION_FAILED",
    "message": "Invalid JWT token",
    "details": "Token has expired",
    "timestamp": "2025-12-01T10:00:00Z"
  }
}

Common Error Codes:

CodeHTTP StatusDescription
AUTHENTICATION_FAILED401Invalid or expired token
AUTHORIZATION_DENIED403Insufficient permissions
RESOURCE_NOT_FOUND404Requested resource doesn't exist
VALIDATION_ERROR400Invalid request parameters
RATE_LIMIT_EXCEEDED429Too many requests
COLD_START_TIMEOUT503Modal service initializing (retry in 30s)
INTERNAL_ERROR500Unexpected server error

Rate Limits

TierRequests/HourConcurrent Requests
Basic1002
Professional1,00010
Enterprise10,00050

Rate Limit Headers:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1733054400

Cold Start Behavior

Modal services sleep after 5-10 minutes of inactivity. First request after sleep:

  • Expected delay: 30-60 seconds
  • HTTP status: 503 (Service Unavailable) or timeout
  • Solution: Retry after 30 seconds

Example retry logic:

async function fetchWithRetry(url: string, retries = 3) {
  for (let i = 0; i < retries; i++) {
    const response = await fetch(url);
    if (response.status !== 503) return response;
    await new Promise(resolve => setTimeout(resolve, 30000));
  }
  throw new Error('Service unavailable after retries');
}

SDK Examples

TypeScript/JavaScript

import { PublicRiskAPI } from '@publicrisk/sdk';

const api = new PublicRiskAPI({
  baseUrl: 'https://publicrisk--publicrisk-consolidated-backend-serve.modal.run',
  apiKey: 'your-jwt-token'
});

// Property risk assessment
const risk = await api.hazus.assessProperty({
  lat: 34.0522,
  lng: -118.2437,
  propertyValue: 500000,
  yearBuilt: 2010
});

console.log(`Overall Risk Score: ${risk.overall_risk.score}`);

// STORM document generation
const job = await api.storm.generate({
  topic: 'Wildfire Risk Assessment',
  template: 'risk_assessment',
  parameters: {
    research_depth: 'comprehensive'
  }
});

const status = await api.storm.getStatus(job.job_id);

Python

from publicrisk_sdk import PublicRiskAPI

api = PublicRiskAPI(
    base_url='https://publicrisk--publicrisk-consolidated-backend-serve.modal.run',
    api_key='your-jwt-token'
)

# RAG document upload
with open('policy.pdf', 'rb') as f:
    result = api.rag.upload(
        file=f,
        rag_store='policy_library',
        category='insurance_policy'
    )

print(f"Uploaded: {result.document_id}")

# Search RAG
results = api.rag.search(
    query='What is the cyber liability limit?',
    rag_store='policy_library',
    limit=5
)

for result in results:
    print(f"Score: {result.score}, Content: {result.content}")


Support

For API support:

On this page

API ReferenceAuthentication & User ManagementPOST /api/auth/loginPOST /api/auth/verify-2faPOST /api/auth/2fa/setupPOST /api/auth/2fa/enableGET /api/auth/2fa/statusPOST /api/auth/change-passwordAdmin & Organization ManagementGET /api/admin/usersPOST /api/admin/usersPOST /api/admin/users/{user_id}/2faGET /api/admin/organizationsGET /api/admin/audit-logsHAZUS Disaster Risk AssessmentGET /healthGET /assess-propertyGET /realtime-allGET /flood-riskGET /earthquake-riskGET /wildfire-riskSTORM Document GenerationPOST /api/dspy/storm/generateGET /api/dspy/storm/status/{job_id}POST /api/dspy/queryRAG ManagementPOST /api/simple-rag/uploadGET /api/simple-rag/documentsGET /api/simple-rag/statsPOST /api/simple-rag/searchDELETE /api/simple-rag/documents/{document_id}Query Explorer (Multi-Engine Analysis)POST /api/query-explorer/analyzeGET /api/query-explorer/status/{job_id}GET /api/query-explorer/jobsDELETE /api/query-explorer/jobs/{job_id}SIPMath SLURP (Correlated Risk Analysis)POST /api/sipmath/create-slurpPOST /api/sipmath/aggregate-slurpPOST /api/sipmath/hazus-to-sipCybersecurity (CISA KEV Integration)GET /api/cyber/kevGET /api/cyber/infrastructure-threatsGET /api/cyber/kev/cve/{cve_id}Data VisualizationPOST /api/dspy/visualization-pipelinePOST /api/dspy/categorize-queryPEFT Adapters (Domain Specialization)GET /api/peft/adaptersPOST /api/peft/inferencePOST /api/peft/trainGET /api/peft/training/status/{job_id}POST /api/peft/testPOST /api/peft/approveError ResponsesRate LimitsCold Start BehaviorSDK ExamplesTypeScript/JavaScriptPythonRelated DocumentationSupport