{
  "openapi": "3.0.3",
  "info": {
    "title": "Nuronus Public API",
    "version": "1.0.0",
    "description": "REST API for reading compliance posture, security scores, risks, and assets from Nuronus.\n\n**Authentication:** every request requires an API key in the `X-API-Key` header. Keys are issued by your Nuronus account administrator, carry explicit scopes (e.g. `read:clients`, `read:compliance`), and can be restricted to specific client organizations and source IPs.\n\n**Rate limits:** 60 requests/minute, 1,000/hour, 10,000/day per key by default. Standard `RateLimit-*` headers are returned; exceeding a limit returns HTTP 429.\n\n**Webhooks (push):** in addition to these pull endpoints, Nuronus can POST events (`compliance_status_changed`, `compliance_drift_detected`, `integration_sync_completed`, `evidence_expiring`, and others) to your endpoint. Deliveries are signed with HMAC-SHA256 of the raw body in the `X-Nuronus-Signature` header, carry `X-Nuronus-Event-Id` for idempotency, and are retried on failure. See https://nuronus.com/docs/api for webhook documentation.",
    "contact": {
      "name": "Nuronus",
      "url": "https://nuronus.com/contact"
    }
  },
  "servers": [
    { "url": "https://nuronus.com/api/v1", "description": "Production" }
  ],
  "security": [{ "ApiKeyAuth": [] }],
  "tags": [
    { "name": "Clients", "description": "Client organizations visible to your API key. Store the `id` (UUID) and pass it in the path of every other request." },
    { "name": "Assets", "description": "Discovered and externally-pushed assets per client." },
    { "name": "Security Scores", "description": "Continuous security scoring with letter grades and history." },
    { "name": "Risks", "description": "Risk items from the latest risk assessment." },
    { "name": "Compliance", "description": "Framework readiness rollups and requirement-keyed compliance detail across all 11 supported frameworks." }
  ],
  "paths": {
    "/clients": {
      "get": {
        "tags": ["Clients"],
        "summary": "List clients",
        "description": "Lists all active client organizations accessible to the API key. Keys restricted to specific clients only see those.",
        "operationId": "listClients",
        "parameters": [
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" },
          { "name": "industry", "in": "query", "description": "Filter by industry", "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Client list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/Client" } },
                    "pagination": { "$ref": "#/components/schemas/Pagination" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" }
        }
      }
    },
    "/clients/{clientId}": {
      "get": {
        "tags": ["Clients"],
        "summary": "Get client details",
        "operationId": "getClient",
        "parameters": [{ "$ref": "#/components/parameters/ClientId" }],
        "responses": {
          "200": {
            "description": "Client details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": { "data": { "$ref": "#/components/schemas/ClientDetail" } }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/clients/{clientId}/assets": {
      "get": {
        "tags": ["Assets"],
        "summary": "List client assets",
        "operationId": "listClientAssets",
        "parameters": [
          { "$ref": "#/components/parameters/ClientId" },
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" },
          { "name": "category", "in": "query", "schema": { "type": "string" } },
          { "name": "assetType", "in": "query", "schema": { "$ref": "#/components/schemas/AssetType" } },
          { "name": "isCritical", "in": "query", "description": "Pass `true` to return only critical assets", "schema": { "type": "string", "enum": ["true"] } }
        ],
        "responses": {
          "200": {
            "description": "Asset list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/Asset" } },
                    "pagination": { "$ref": "#/components/schemas/Pagination" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/assets": {
      "post": {
        "tags": ["Assets"],
        "summary": "Create an asset",
        "description": "Creates an asset in Nuronus — useful for pushing inventory from an external system. Requires the `write:assets` scope. `externalId` is your system's identifier.",
        "operationId": "createAsset",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": { "schema": { "$ref": "#/components/schemas/AssetCreate" } }
          }
        },
        "responses": {
          "201": {
            "description": "Asset created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": { "data": { "$ref": "#/components/schemas/Asset" } }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/assets/{assetId}": {
      "put": {
        "tags": ["Assets"],
        "summary": "Update an asset",
        "operationId": "updateAsset",
        "parameters": [
          { "name": "assetId", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": { "schema": { "$ref": "#/components/schemas/AssetUpdate" } }
          }
        },
        "responses": {
          "200": {
            "description": "Asset updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": { "data": { "$ref": "#/components/schemas/Asset" } }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/clients/{clientId}/scores": {
      "get": {
        "tags": ["Security Scores"],
        "summary": "Get security scores",
        "description": "Current security score with letter grade (A ≥ 90, B ≥ 80, C ≥ 70, D ≥ 60, F below) plus history.",
        "operationId": "getClientScores",
        "parameters": [
          { "$ref": "#/components/parameters/ClientId" },
          { "name": "limit", "in": "query", "description": "Historical entries to return (default 30, max 100)", "schema": { "type": "integer", "default": 30, "maximum": 100 } }
        ],
        "responses": {
          "200": {
            "description": "Scores",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "current": { "$ref": "#/components/schemas/SecurityScore" },
                        "history": { "type": "array", "items": { "$ref": "#/components/schemas/SecurityScore" } }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/clients/{clientId}/risks": {
      "get": {
        "tags": ["Risks"],
        "summary": "List risk items",
        "description": "Risk items from the client's latest risk assessment, ordered by risk score descending.",
        "operationId": "listClientRisks",
        "parameters": [
          { "$ref": "#/components/parameters/ClientId" },
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Offset" },
          { "name": "severity", "in": "query", "schema": { "type": "string", "enum": ["critical", "high", "medium", "low"] } }
        ],
        "responses": {
          "200": {
            "description": "Risk items",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/RiskItem" } },
                    "pagination": { "$ref": "#/components/schemas/Pagination" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/clients/{clientId}/compliance": {
      "get": {
        "tags": ["Compliance"],
        "summary": "Compliance rollup (all frameworks)",
        "description": "High-level rollup per framework: readiness score and control pass/partial/fail counts. Use the requirement-keyed endpoint for per-requirement detail.",
        "operationId": "getClientCompliance",
        "parameters": [{ "$ref": "#/components/parameters/ClientId" }],
        "responses": {
          "200": {
            "description": "Per-framework rollup",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "type": "array", "items": { "$ref": "#/components/schemas/ComplianceSummary" } }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/clients/{clientId}/compliance/{frameworkId}": {
      "get": {
        "tags": ["Compliance"],
        "summary": "Requirement-keyed compliance detail",
        "description": "Compliance status keyed by the framework's own control references — SOC 2 `CC6.1`, HIPAA `164.312(a)(1)`, CMMC `AC.L2-3.1.1`, FERPA `99.31(c)` — so results join directly against external GRC control tables. Each requirement carries an overall status, a 0–100 compliance score, and the mapped technical control results as supporting detail.",
        "operationId": "getClientComplianceByFramework",
        "parameters": [
          { "$ref": "#/components/parameters/ClientId" },
          {
            "name": "frameworkId",
            "in": "path",
            "required": true,
            "description": "Framework identifier (case-insensitive)",
            "schema": {
              "type": "string",
              "enum": ["HIPAA", "SOC2", "PCI_DSS", "NIST_CSF", "ISO_27001", "CJIS", "CMMC_L1", "CMMC_L2", "FERPA", "PIPEDA", "LOI_25"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Requirement-keyed detail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": { "$ref": "#/components/schemas/ComplianceDetail" }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "403": { "$ref": "#/components/responses/Forbidden" },
          "404": { "description": "Client or framework not found — the error message lists supported framework IDs", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "API key in the form `nuronus_<prefix>_<secret>`, issued by your Nuronus account administrator."
      }
    },
    "parameters": {
      "ClientId": {
        "name": "clientId",
        "in": "path",
        "required": true,
        "description": "Nuronus client UUID (from GET /clients)",
        "schema": { "type": "string", "format": "uuid" }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "description": "Page size (max 100)",
        "schema": { "type": "integer", "default": 50, "maximum": 100 }
      },
      "Offset": {
        "name": "offset",
        "in": "query",
        "schema": { "type": "integer", "default": 0 }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "Forbidden": {
        "description": "API key lacks the required scope or is not authorized for this client",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      },
      "BadRequest": {
        "description": "Validation error",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": false },
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "string", "example": "FORBIDDEN" },
              "message": { "type": "string", "example": "API key missing required scope: read:compliance" }
            }
          }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "total": { "type": "integer", "example": 12 },
          "limit": { "type": "integer", "example": 50 },
          "offset": { "type": "integer", "example": 0 }
        }
      },
      "Client": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "name": { "type": "string", "example": "Acme Medical Group" },
          "industry": { "type": "string", "nullable": true, "example": "healthcare" },
          "employeeCount": { "type": "integer", "nullable": true, "example": 45 },
          "createdAt": { "type": "string", "format": "date-time" }
        }
      },
      "ClientDetail": {
        "allOf": [
          { "$ref": "#/components/schemas/Client" },
          {
            "type": "object",
            "properties": {
              "settings": { "type": "object" },
              "updatedAt": { "type": "string", "format": "date-time" }
            }
          }
        ]
      },
      "AssetType": {
        "type": "string",
        "enum": ["user", "device", "server", "workstation", "mobile", "network_device", "virtual_machine", "container", "saas_app", "cloud_resource", "identity", "mailbox", "file_share", "database"]
      },
      "Asset": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "name": { "type": "string", "example": "FILESRV01" },
          "displayName": { "type": "string", "nullable": true },
          "category": { "type": "string", "nullable": true, "example": "infrastructure" },
          "assetType": { "$ref": "#/components/schemas/AssetType" },
          "status": { "type": "string", "example": "active" },
          "isCritical": { "type": "boolean" },
          "isManaged": { "type": "boolean" },
          "owner": { "type": "string", "nullable": true },
          "riskScore": { "type": "number", "nullable": true },
          "firstDiscoveredAt": { "type": "string", "format": "date-time" },
          "lastUpdatedAt": { "type": "string", "format": "date-time" }
        }
      },
      "AssetCreate": {
        "type": "object",
        "required": ["clientId", "name", "externalId", "assetType"],
        "properties": {
          "clientId": { "type": "string", "format": "uuid" },
          "name": { "type": "string", "maxLength": 500 },
          "displayName": { "type": "string", "maxLength": 500 },
          "externalId": { "type": "string", "maxLength": 500, "description": "Your system's identifier for this asset" },
          "assetType": { "$ref": "#/components/schemas/AssetType" },
          "category": { "type": "string", "maxLength": 100 },
          "isCritical": { "type": "boolean", "default": false },
          "owner": { "type": "string", "maxLength": 255 },
          "description": { "type": "string" },
          "tags": { "type": "array", "items": { "type": "string" } }
        }
      },
      "AssetUpdate": {
        "type": "object",
        "properties": {
          "name": { "type": "string", "maxLength": 500 },
          "displayName": { "type": "string", "maxLength": 500, "nullable": true },
          "category": { "type": "string", "maxLength": 100, "nullable": true },
          "isCritical": { "type": "boolean" },
          "owner": { "type": "string", "maxLength": 255, "nullable": true },
          "description": { "type": "string", "nullable": true },
          "tags": { "type": "array", "items": { "type": "string" } }
        }
      },
      "SecurityScore": {
        "type": "object",
        "nullable": true,
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "overallScore": { "type": "integer", "example": 82 },
          "grade": { "type": "string", "enum": ["A", "B", "C", "D", "F"], "example": "B" },
          "categoryScores": { "type": "object", "example": { "identity": 68, "endpoint_protection": 81 } },
          "controlsTotal": { "type": "integer", "example": 45 },
          "controlsCompliant": { "type": "integer", "example": 34 },
          "controlsPartial": { "type": "integer", "example": 6 },
          "controlsNonCompliant": { "type": "integer", "example": 5 },
          "calculatedAt": { "type": "string", "format": "date-time" }
        }
      },
      "RiskItem": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "title": { "type": "string", "example": "Admin accounts without MFA" },
          "description": { "type": "string" },
          "category": { "type": "string", "example": "identity" },
          "severity": { "type": "string", "enum": ["critical", "high", "medium", "low"] },
          "dollarImpact": { "type": "number", "nullable": true },
          "riskScore": { "type": "number" },
          "sourceType": { "type": "string" },
          "createdAt": { "type": "string", "format": "date-time" }
        }
      },
      "ComplianceSummary": {
        "type": "object",
        "properties": {
          "framework": { "type": "string", "example": "CIS_V8" },
          "totalControls": { "type": "integer", "example": 45 },
          "passedControls": { "type": "integer", "example": 27 },
          "partialControls": { "type": "integer", "example": 9 },
          "failedControls": { "type": "integer", "example": 9 },
          "readinessScore": { "type": "integer", "example": 70 }
        }
      },
      "ComplianceStatus": {
        "type": "string",
        "enum": ["compliant", "partial", "non_compliant", "not_assessed", "not_applicable"],
        "description": "For a binary met / not-met interpretation, treat `compliant` as met."
      },
      "ControlResult": {
        "type": "object",
        "properties": {
          "controlCode": { "type": "string", "example": "CIS-6.3" },
          "title": { "type": "string", "example": "Require MFA for Externally-Exposed Applications" },
          "status": { "$ref": "#/components/schemas/ComplianceStatus" },
          "score": { "type": "integer", "nullable": true, "example": 40 },
          "findings": { "type": "string", "nullable": true, "example": "12 of 45 users have no MFA method registered." },
          "remediation": { "type": "string", "nullable": true },
          "assessedAt": { "type": "string", "format": "date-time", "nullable": true }
        }
      },
      "RequirementStatus": {
        "type": "object",
        "properties": {
          "requirement": { "type": "string", "example": "CC6.1", "description": "The framework's own control reference (CC6.1, 164.312(a)(1), AC.L2-3.1.1, 99.31(c), ...)" },
          "description": { "type": "string" },
          "overallStatus": { "$ref": "#/components/schemas/ComplianceStatus" },
          "complianceScore": { "type": "integer", "example": 62, "description": "0–100" },
          "controls": { "type": "array", "items": { "$ref": "#/components/schemas/ControlResult" } }
        }
      },
      "ComplianceDetail": {
        "type": "object",
        "properties": {
          "frameworkId": { "type": "string", "example": "SOC2" },
          "frameworkName": { "type": "string", "example": "SOC 2 Type II" },
          "frameworkVersion": { "type": "string", "example": "2017" },
          "requirements": { "type": "array", "items": { "$ref": "#/components/schemas/RequirementStatus" } }
        }
      }
    }
  }
}
