Skip to content

Backend API Architecture

The RAPID AI backend API is the contract layer between the frontend application and the diagnostic intelligence engine. Every diagnostic inference, RCM decision, maintenance plan, and dashboard payload flows through this API. It is built on FastAPI with Pydantic v2 models, designed for correctness first, performance second, and auditability always.


The RAPID AI API follows six design principles:

1. Resource-oriented REST. Endpoints are organized around resources (assets, diagnostics, maintenance plans) rather than actions. The URL identifies the resource; the HTTP method specifies the action.

2. JSON:API-inspired response format. All responses follow a consistent envelope:

{
"data": { ... },
"meta": {
"request_id": "req_abc123",
"timestamp": "2026-03-14T19:00:00+05:30",
"processing_time_ms": 342
}
}

Collection responses include pagination metadata. Error responses use a distinct error key (see Section 20.5).

3. Versioned endpoints. All routes are prefixed with /rapid-ai/v1/. Breaking changes require a new version. Non-breaking additions (new optional fields, new endpoints) are added to the current version.

4. Consistent error codes. Every error response includes a machine-readable error_code string (e.g., ASSET_NOT_FOUND, SENSOR_DATA_INVALID) alongside a human-readable message. Frontend code switches on error codes, not message text.

5. Audit trail by default. Every request is logged with its request_id, authenticated user, endpoint, response status, and processing time. For diagnostic and RCM endpoints, full request and response payloads are logged for engineering traceability.

6. Rate limiting per API key. External integrations are rate-limited by tier. Internal web sessions have higher limits. All limits return 429 Too Many Requests with a Retry-After header.


Session-based (web application): The SvelteKit frontend uses better-auth for session management. Sessions are stored server-side with HTTP-only cookies. The SvelteKit BFF proxies requests to FastAPI with a service-to-service JWT token, so FastAPI never sees raw session cookies.

API key (external integrations): Third-party systems (CMMS, SCADA historians) authenticate with API keys passed in the X-API-Key header. Keys are scoped: read (GET only), read-write (GET + POST), or admin (all operations).

Service-to-service JWT: Internal communication between SvelteKit and FastAPI uses short-lived JWT tokens (5-minute expiry) signed with RS256. The SvelteKit server holds the private key; FastAPI validates with the public key.

Every endpoint enforces role-based access at the middleware level:

Endpoint PatternAllowed Roles
GET /rapid-ai/v1/healthPublic (no auth required)
GET /rapid-ai/v1/assets/*, GET /rapid-ai/v1/dashboard/*, GET /rapid-ai/v1/reference/*All authenticated roles
POST /rapid-ai/v1/assets/{id}/diagnose, POST .../end-to-end-evaluateengineer, operator
POST /rapid-ai/v1/assets/{id}/rcm-decisionengineer
POST /rapid-ai/v1/assets/{id}/maintenance-planengineer, maintenance_manager
PUT /rapid-ai/v1/rcm/*engineer, maintenance_manager
DELETE /rapid-ai/v1/*, POST /rapid-ai/v1/admin/*admin
GET /rapid-ai/v1/admin/auditadmin, plant_manager
TierRequests/MinuteApplies To
Web session300Authenticated web users
API key (standard)60External integrations
API key (premium)300High-frequency SCADA integrations

The engine exposes one API version: v1. All endpoints are under the /rapid-ai/v1/ prefix.

MethodPathPurpose
POST/rapid-ai/v1/evaluateFull 5-module pipeline (mA→mB→mC→mD→mE)
POST/rapid-ai/v1/moduleASignal analysis only
POST/rapid-ai/v1/moduleBFault detection only
POST/rapid-ai/v1/moduleCSSI fusion only
POST/rapid-ai/v1/moduleDPrognostics only
POST/rapid-ai/v1/moduleEMaintenance planning only
POST/rapid-ai/v1/diagnoseAI diagnostician (feature-gated)

The /v1/evaluate endpoint is the primary operational endpoint. It runs the full pipeline and returns:

class AnalysisResult(BaseModel):
request_id: str
timestamp: str
version: str # "2.3.0"
signal_analysis: SignalAnalysis # mA output
fault_detection: FaultDetection # mB output
fused_indicators: FusedIndicators # mC output
prognostics: Prognostics # mD output
maintenance_plan: MaintenancePlan # mE output
brief: Optional[Brief] # AI narrative (if AI_BRIEF enabled)
diagnostics: Optional[Diagnostics] # AI RCA (if AI_DIAGNOSTICIAN enabled)
MethodPathPurpose
GET/rapid-ai/v1/healthService health check

6-level hierarchy: Organisation → Location → Area → Equipment → Sub-Assembly → Measurement Point.

MethodPathPurpose
GET/POST/rapid-ai/assets/organisationsCRUD organisations
GET/POST/rapid-ai/assets/locations/{org_id}Locations in org
GET/POST/rapid-ai/assets/areas/{location_id}Areas in location
GET/POST/rapid-ai/assets/equipment/{area_id}Equipment in area
GET/rapid-ai/assets/equipment/{id}/contextEquipment + subs + points + spares
GET/rapid-ai/assets/equipment/{id}/treeFull hierarchy tree
GET/POST/rapid-ai/assets/sub-assemblies/{equipment_id}Sub-assemblies
GET/POST/rapid-ai/assets/measurement-points/{sub_id}Measurement points
MethodPathPurpose
GET/rapid-ai/assets/sparesAll spares (flat list)
GET/rapid-ai/assets/spares/low-stock?threshold=2Low-stock filter
GET/rapid-ai/assets/spares/detail/{id}Single spare with context
GET/rapid-ai/assets/spares/by-sub-assembly/{sub_id}Spares per sub-assembly
PATCH/rapid-ai/assets/spares/{id}/stockAdjust stock by delta

Multi-agent system for complex diagnostic workflows:

MethodPathPurpose
POST/rapid-ai/swarm/taskSubmit pre-built AgentTask
POST/rapid-ai/swarm/dispatchIntent-based dispatch (plans → executes)
GET/rapid-ai/swarm/capabilitiesList all worker capabilities
GET/rapid-ai/swarm/statusActive workers, task count
GET/rapid-ai/swarm/streamSSE stream (heartbeats + swarm events)
MethodPathPurpose
GET/rapid-ai/knowledge/search?q=...&top_k=5Semantic search across rules + analyses

Rules are synced to pgvector (768-dim embeddings) on startup with content-hash deduplication — 0 API calls after initial sync.

MethodPathPurpose
POST/rapid-ai/generate-signalSynthetic signal for testing
GET /health → {
"status": "healthy",
"version": "2.3.0",
"features": {
"ai_brief": true,
"ai_diagnostician": true,
"rag_rules": true,
"v2_pipeline": true,
"swarm_engine": true,
"swarm_explorer": true
},
"providers": {
"gemini": { "status": "available", "capabilities": ["text", "tools", "embedding"] }
}
}

All request and response schemas are defined as Pydantic v2 BaseModel classes in engine/engine/models/. Key models from the production codebase:

class AnalysisRequest(BaseModel):
machine_type: str # motor_pump_train, centrifugal_pump, etc.
component_type: str # afb, coupling, motor, gearbox, etc.
measurement_points: List[str] # bearing_1_axial, bearing_1_radial, temp_1
signals: Dict[str, List[float]] # {point_id: [samples...]}
sampling_rate: int # Hz
duration_seconds: float # measurement duration

Physics module signatures follow a consistent pattern:

def analyze_signal(request: AnalysisRequest) -> SignalAnalysis: ...
def detect_faults(request: FaultRequest) -> FaultDetection: ...
def fuse_ssi(request: FusionRequest) -> FusedIndicators: ...
def predict_prognostics(request: PrognosticsRequest) -> Prognostics: ...
def plan_maintenance(request: MaintenanceRequest) -> MaintenancePlan: ...

SSOT type chain: Python Pydantic → FastAPI auto-generates OpenAPI spec → openapi-typescript generates TypeScript → @rapidai/contracts package → SvelteKit app imports types. Generate with make gen-types.

Custom validators enforce domain-specific rules at the API boundary: component_type must be one of 12 known types; sampling_rate must be in the allowed set (256–51200 Hz); signals must contain at least one measurement point.

OpenAPI documentation is auto-generated, available at /docs (Swagger UI) and /openapi.json.


All errors follow a consistent structure:

{
"error": {
"error_code": "ASSET_NOT_FOUND",
"message": "Asset with ID 'X-999' does not exist in the registry.",
"details": { "asset_id": "X-999", "suggestion": "Verify the asset ID or register the asset first." },
"request_id": "req_abc123"
}
}
Error CodeHTTP StatusMeaning
ASSET_NOT_FOUND404Asset ID not in registry
SENSOR_DATA_INVALID422Sensor readings fail validation
SENSOR_DATA_MISSING422No sensor groups provided
RULE_EVALUATION_FAILED500Diagnostic rule engine error
CONFIDENCE_BELOW_THRESHOLD200Completed but confidence too low for action
RCM_CONTEXT_INCOMPLETE422Missing required decision context fields
MAINTENANCE_PLAN_CONFLICT409Conflicting plan for time window
RATE_LIMIT_EXCEEDED429Too many requests
UNAUTHORIZED / FORBIDDEN401 / 403Missing credentials / insufficient role

Stack traces are never included in production responses — they are logged server-side with the request_id for correlation. All 5xx errors trigger ops alerts.


FastAPI middleware executes in order for every request:

Request → Request ID → Logging → CORS → Rate Limit → Auth → AuthZ → Handler → Response Log → Error Handler → Response

Request ID: Every request receives a UUID v4 request_id attached as X-Request-ID. This ID threads through all log entries, audit records, and error responses for end-to-end traceability.

CORS: Configurable origin allowlist — localhost:5173 in development, deployed frontend domain only in production.

Authentication: Attempts auth in order: (1) session cookie, (2) X-API-Key header, (3) Authorization: Bearer JWT. First successful method wins.

Authorization: User role checked against endpoint’s required roles. Insufficient permissions return 403 FORBIDDEN.


Input protection: All database access uses parameterized queries via SQLAlchemy (FastAPI) and Drizzle ORM (SvelteKit). No string concatenation of SQL. The rule evaluator uses a safe recursive-descent parser — eval() and exec() are prohibited by linting rules. String inputs are stripped of control characters; copilot messages are sanitized before storage.

Transport security: HTTPS only in production with HSTS (max-age=31536000; includeSubDomains). Security headers on all responses: Content-Security-Policy, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin.

Dependency security: pip-audit (Python) and npm audit (frontend) run in CI. Dependabot or Renovate monitors for security patches.

API key management: Keys are bcrypt-hashed in the database; plaintext shown only at creation. Configurable expiration (default: 1 year). New keys can be issued while old keys remain valid for a 7-day grace period. Revoked keys return 401 immediately.


RAPID AI integrates with existing plant systems through four patterns:

When a diagnostic result changes an asset’s state (e.g., Normal to Warning), RAPID AI fires webhooks to configured endpoints — SAP PM (creates maintenance notifications), IBM Maximo (updates work order priority by RPN), Fiix CMMS (pushes tasks with spare part requirements). Failed deliveries retry with exponential backoff (3 attempts over 15 minutes).

Historical sensor data is imported via POST /api/v1/import/sensor-data, accepting up to 10,000 readings per request. Processing is asynchronous — the endpoint returns 202 Accepted with a job ID for status polling.

FormatEndpointContent
CSVGET /api/v1/export/diagnostics?format=csvDiagnostic history
PDFGET /api/v1/export/report/{assetId}Formatted engineering report with charts
JSONGET /api/v1/export/diagnostics?format=jsonRaw diagnostic data

An MQTT bridge service subscribes to sensor data topics from OSIsoft PI (via PI Web API), Wonderware/AVEVA Historian (via OPC-UA gateway), and direct SCADA systems. The bridge normalizes incoming data into the SensorInputs schema, then writes to the time-series database, pushes to WebSocket clients, and optionally triggers automatic diagnostic evaluation for continuously monitored assets.

SCADA/Historian → MQTT → Bridge Service → Normalize → DB + WebSocket + Auto-Diagnose

This enables two operating modes: on-demand (engineer triggers diagnostic via UI/API) and continuous (diagnostics run automatically at configurable intervals or on threshold breach).


Next: Chapter 21 covers the deployment and operations architecture — CI/CD pipelines, container orchestration, monitoring, and the path from development to production.


StandardRelevance to This Chapter
ISO 13374 — Condition monitoring and diagnostics of machinesThe REST API endpoints (/evaluate, /diagnose, /moduleA through /moduleD) expose ISO 13374 processing levels as individually addressable services, enabling both full pipeline and per-level integration.
MIMOSA OSA-CBM — Open System Architecture for CBMThe JSON:API-inspired response format and consistent error codes implement OSA-CBM’s data exchange requirements for interoperable condition-based maintenance systems.
OWASP Top 10 — Web application securityThe API design principles (consistent error codes, request validation, rate limiting, CORS configuration) address multiple OWASP Top 10 categories including A01 (Broken Access Control), A03 (Injection), and A07 (Identification and Authentication Failures).
IEC 62443 — Industrial cybersecurityThe versioned API endpoints and authentication middleware implement IEC 62443’s requirements for secure communication and access control in industrial automation systems.
VersionDateAuthorChanges
2.1.02026-03-17Rick DAdded standards alignment, living doc metadata, changelog
2.0.02026-03-17Rick DEnriched with production codebase content
1.0.02026-03-17Rick DInitial chapter creation