{"openapi":"3.1.0","info":{"title":"Asiri Public API","version":"local-dev","description":"External ASIRI API surface for tenant API keys. App-only, staff-only, and session-only routes are intentionally excluded."},"servers":[{"url":"https://api.asiri.ng","description":"this server"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"asiri_<env>_<token>","description":"Tenant API key passed as Authorization: Bearer <token>."}}},"paths":{"/v1/audit":{"get":{"tags":["audit"],"summary":"List audit log events for the current tenant","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["audit:read"],"parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64},"required":false,"name":"module","in":"query"},{"schema":{"type":"string","enum":["user","api_key","system","staff"]},"required":false,"name":"actor","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"from","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"to","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"List audit log events for the current tenant","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"actorId":{"type":["string","null"]},"actorEmail":{"type":["string","null"]},"actorType":{"type":"string","enum":["user","api_key","system","staff"]},"action":{"type":"string"},"module":{"type":"string"},"targetId":{"type":["string","null"]},"targetRef":{"type":["string","null"]},"hash":{"type":"string"},"prevHash":{"type":["string","null"]}},"required":["id","at","actorId","actorEmail","actorType","action","module","targetId","targetRef","hash","prevHash"],"additionalProperties":false}},"nextCursor":{"type":["string","null"]}},"required":["items","nextCursor"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `audit:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/audit/{id}":{"get":{"tags":["audit"],"summary":"Get a single audit event with hash + diff","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["audit:read"],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Get a single audit event with hash + diff","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","format":"date-time"},"actorId":{"type":["string","null"]},"actorEmail":{"type":["string","null"]},"actorType":{"type":"string","enum":["user","api_key","system","staff"]},"action":{"type":"string"},"module":{"type":"string"},"targetId":{"type":["string","null"]},"targetRef":{"type":["string","null"]},"hash":{"type":"string"},"prevHash":{"type":["string","null"]},"ip":{"type":["string","null"]},"userAgent":{"type":["string","null"]},"diff":{},"reason":{"type":["string","null"]}},"required":["id","at","actorId","actorEmail","actorType","action","module","targetId","targetRef","hash","prevHash","ip","userAgent","reason"],"additionalProperties":false}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `audit:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/consent":{"get":{"tags":["consent"],"summary":"List consent notices","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["consent:read"],"parameters":[{"schema":{"type":"string","enum":["draft","published","archived"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string"},"required":false,"name":"domain","in":"query"},{"schema":{"type":"string"},"required":false,"name":"search","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"List consent notices","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{}}},"page":{"type":"object","properties":{"cursor":{"type":["string","null"]},"nextCursor":{"type":["string","null"]},"limit":{"type":"number"},"total":{"type":"number"}},"required":["cursor","nextCursor","limit","total"]}},"required":["data","page"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `consent:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/consent/{id}":{"get":{"tags":["consent"],"summary":"Get a consent notice by id","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["consent:read"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Get a consent notice by id","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{}}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `consent:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/consent/{id}/records":{"get":{"tags":["consent"],"summary":"List consent records captured against a notice","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["consent:read"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"List consent records captured against a notice","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{}}},"page":{"type":"object","properties":{}}},"required":["data","page"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `consent:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."},"post":{"tags":["consent"],"summary":"Capture a new consent record (append-only)","description":"Captures a single consent record against a published notice. The notice MUST be in status='published'; a draft or archived notice returns 409 conflict with `code: \"consent_notice_not_published\"` and `requiredStatus` / `actualStatus` fields on the error envelope. Publish via POST /v1/consent/{id}/publish before capturing. The records ledger is append-only — withdrawals create a new linked row rather than mutating the original.\n\nRequired API key scope: `consent:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["consent:write"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"subjectId":{"type":"string","minLength":1},"subjectChannel":{"type":"string","enum":["email","phone","subject_id"]},"ip":{"type":"string"},"ua":{"type":"string"},"method":{"type":"string","enum":["banner","modal","inline","checkbox","double_opt_in","verbal_recorded"]},"purposes":{"type":"object","additionalProperties":{"type":"boolean"}},"capturedAt":{"type":"string","format":"date-time"}},"required":["subjectId","purposes"]}}}},"responses":{"201":{"description":"Captures a single consent record against a published notice. The notice MUST be in status='published'; a draft or archived notice returns 409 conflict with `code: \"consent_notice_not_published\"` and `requiredStatus` / `actualStatus` fields on the error envelope. Publish via POST /v1/consent/{id}/publish before capturing. The records ledger is append-only — withdrawals create a new linked row rather than mutating the original.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{}}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"x-asiri-idempotency":"required"}},"/v1/consent/{id}/records/{recordId}":{"get":{"tags":["consent"],"summary":"Get a single consent record","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["consent:read"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid"},"required":true,"name":"recordId","in":"path"}],"responses":{"200":{"description":"Get a single consent record","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{}}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `consent:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework":{"get":{"tags":["controls","evidence"],"summary":"List tenant controls with framework mappings and evidence status","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:read"],"responses":{"200":{"description":"List tenant controls with framework mappings and evidence status","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"summary":{"type":"object","properties":{"catalogControls":{"type":"integer"},"tenantControls":{"type":"integer"},"implemented":{"type":"integer"},"needsEvidence":{"type":"integer"},"failing":{"type":"integer"},"frameworks":{"type":"integer"}},"required":["catalogControls","tenantControls","implemented","needsEvidence","failing","frameworks"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"controlId":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"domain":{"type":"string"},"status":{"type":"string","enum":["not_started","in_progress","evidence_requested","evidence_submitted","implemented","needs_review","accepted","overdue","not_applicable","excepted"]},"cadence":{"type":"string","enum":["monthly","quarterly","semi_annual","annual","event_driven"]},"ownerUserId":{"type":["string","null"],"format":"uuid"},"evidenceFreshness":{"type":"string","enum":["current","stale","expired","missing"]},"latestResultStatus":{"type":["string","null"],"enum":["pass","fail","warning","manual","unknown"]},"lastTestedAt":{"type":["string","null"],"format":"date-time"},"nextReviewAt":{"type":["string","null"],"format":"date-time"},"mappedFrameworks":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"requirements":{"type":"array","items":{"type":"string"}}},"required":["code","name","requirements"]}},"evidenceCount":{"type":"integer"},"testCount":{"type":"integer"},"resultCount":{"type":"integer"}},"required":["id","controlId","code","title","description","domain","status","cadence","ownerUserId","evidenceFreshness","latestResultStatus","lastTestedAt","nextReviewAt","mappedFrameworks","evidenceCount","testCount","resultCount"]}}},"required":["summary","items"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework/frameworks":{"get":{"tags":["controls","evidence"],"summary":"List active control frameworks and public assurance boundaries","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:read"],"responses":{"200":{"description":"List active control frameworks and public assurance boundaries","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"jurisdiction":{"type":["string","null"]},"versionLabel":{"type":["string","null"]},"category":{"type":["string","null"]},"scopeSummary":{"type":["string","null"]},"assuranceBoundary":{"type":["string","null"]},"allowedClaim":{"type":["string","null"]},"prohibitedClaims":{"type":"array","items":{"type":"string"}}},"required":["code","name","description","jurisdiction","versionLabel","category","scopeSummary","assuranceBoundary","allowedClaim","prohibitedClaims"]}}},"required":["items"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework/readiness":{"get":{"tags":["controls","evidence"],"summary":"Get tenant readiness summary by framework and control domain","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:read"],"responses":{"200":{"description":"Get tenant readiness summary by framework and control domain","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"score":{"type":"integer"},"totalControls":{"type":"integer"},"acceptedControls":{"type":"integer"},"openEvidenceRequests":{"type":"integer"},"overdueEvidenceRequests":{"type":"integer"},"frameworkReadiness":{"type":"object","additionalProperties":{"type":"object","properties":{"total":{"type":"integer"},"accepted":{"type":"integer"},"submitted":{"type":"integer"},"open":{"type":"integer"},"overdue":{"type":"integer"},"score":{"type":"integer"}},"required":["total","accepted","submitted","open","overdue","score"]}},"domainReadiness":{"type":"object","additionalProperties":{"type":"object","properties":{"total":{"type":"integer"},"accepted":{"type":"integer"},"submitted":{"type":"integer"},"open":{"type":"integer"},"overdue":{"type":"integer"},"score":{"type":"integer"}},"required":["total","accepted","submitted","open","overdue","score"]}}},"required":["score","totalControls","acceptedControls","openEvidenceRequests","overdueEvidenceRequests","frameworkReadiness","domainReadiness"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework/test-health":{"get":{"tags":["controls","evidence"],"summary":"List control test health with scheduled runs and evidence counts","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:read"],"responses":{"200":{"description":"List control test health with scheduled runs and evidence counts","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"summary":{"type":"object","properties":{"totalControls":{"type":"integer"},"failing":{"type":"integer"},"warning":{"type":"integer"},"passing":{"type":"integer"},"unknown":{"type":"integer"},"currentEvidence":{"type":"integer"},"staleEvidence":{"type":"integer"},"expiredEvidence":{"type":"integer"},"missingEvidence":{"type":"integer"},"needsEvidence":{"type":"integer"},"missingTests":{"type":"integer"},"dueTests":{"type":"integer"}},"required":["totalControls","failing","warning","passing","unknown","currentEvidence","staleEvidence","expiredEvidence","missingEvidence","needsEvidence","missingTests","dueTests"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"controlId":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"domain":{"type":"string"},"status":{"type":"string","enum":["not_started","in_progress","evidence_requested","evidence_submitted","implemented","needs_review","accepted","overdue","not_applicable","excepted"]},"cadence":{"type":"string","enum":["monthly","quarterly","semi_annual","annual","event_driven"]},"ownerUserId":{"type":["string","null"],"format":"uuid"},"evidenceFreshness":{"type":"string","enum":["current","stale","expired","missing"]},"latestResultStatus":{"type":["string","null"],"enum":["pass","fail","warning","manual","unknown"]},"lastTestedAt":{"type":["string","null"],"format":"date-time"},"nextReviewAt":{"type":["string","null"],"format":"date-time"},"mappedFrameworks":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"requirements":{"type":"array","items":{"type":"string"}}},"required":["code","name","requirements"]}},"evidenceCount":{"type":"integer"},"testCount":{"type":"integer"},"resultCount":{"type":"integer"},"tests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"key":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"kind":{"type":"string","enum":["manual","automated","connector_query","document_check"]},"cadence":{"type":"string","enum":["monthly","quarterly","semi_annual","annual","event_driven"]},"isActive":{"type":"boolean"},"lastRunAt":{"type":["string","null"],"format":"date-time"},"nextRunAt":{"type":["string","null"],"format":"date-time"},"isDue":{"type":"boolean"},"latestStatus":{"type":"string","enum":["pass","fail","warning","manual","unknown"]},"latestResultAt":{"type":["string","null"],"format":"date-time"},"failureReason":{"type":["string","null"]},"remediationGuidance":{"type":["string","null"]}},"required":["id","key","title","description","kind","cadence","isActive","lastRunAt","nextRunAt","isDue","latestStatus","latestResultAt","failureReason","remediationGuidance"]}}},"required":["id","controlId","code","title","description","domain","status","cadence","ownerUserId","evidenceFreshness","latestResultStatus","lastTestedAt","nextReviewAt","mappedFrameworks","evidenceCount","testCount","resultCount","tests"]}}},"required":["summary","items"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework/monitoring":{"get":{"tags":["controls","evidence"],"summary":"Summarise continuous monitoring signals across controls and evidence workflows","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:read"],"responses":{"200":{"description":"Summarise continuous monitoring signals across controls and evidence workflows","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"monitoredControls":{"type":"integer"},"failingControls":{"type":"integer"},"staleEvidenceControls":{"type":"integer"},"overdueEvidenceRequests":{"type":"integer"},"dueTests":{"type":"integer"},"openWorkflowTasks":{"type":"integer"},"criticalWorkflowTasks":{"type":"integer"},"lastSignalAt":{"type":["string","null"],"format":"date-time"},"attentionItems":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["failing_check","stale_evidence","overdue_evidence","due_test","critical_task"]},"severity":{"type":"string","enum":["info","warning","critical"]},"title":{"type":"string"},"detail":{"type":"string"},"controlId":{"type":["string","null"],"format":"uuid"},"controlCode":{"type":["string","null"]},"targetHref":{"type":"string"},"detectedAt":{"type":"string","format":"date-time"}},"required":["id","kind","severity","title","detail","controlId","controlCode","targetHref","detectedAt"]}}},"required":["monitoredControls","failingControls","staleEvidenceControls","overdueEvidenceRequests","dueTests","openWorkflowTasks","criticalWorkflowTasks","lastSignalAt","attentionItems"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework/coverage":{"get":{"tags":["controls","evidence"],"summary":"List evidence-to-control coverage with blockers and audit-readiness status","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:read"],"responses":{"200":{"description":"List evidence-to-control coverage with blockers and audit-readiness status","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"generatedAt":{"type":"string","format":"date-time"},"summary":{"type":"object","properties":{"totalControls":{"type":"integer"},"auditReadyControls":{"type":"integer"},"blockedControls":{"type":"integer"},"evidenceCurrentControls":{"type":"integer"},"openTaskControls":{"type":"integer"}},"required":["totalControls","auditReadyControls","blockedControls","evidenceCurrentControls","openTaskControls"]},"items":{"type":"array","items":{"type":"object","properties":{"tenantControlId":{"type":"string","format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"},"domain":{"type":"string"},"ownerUserId":{"type":["string","null"],"format":"uuid"},"ownerRole":{"type":["string","null"]},"status":{"type":"string","enum":["not_started","in_progress","evidence_requested","evidence_submitted","implemented","needs_review","accepted","overdue","not_applicable","excepted"]},"evidenceFreshness":{"type":"string","enum":["current","stale","expired","missing"]},"latestResultStatus":{"type":["string","null"],"enum":["pass","fail","warning","manual","unknown"]},"auditReady":{"type":"boolean"},"blocker":{"type":["string","null"]},"readiness":{"type":"object","properties":{"policyKey":{"type":"string","enum":["strict_assurance","standard_assurance"]},"frameworkCodes":{"type":"array","items":{"type":"string"}},"score":{"type":"integer","minimum":0,"maximum":100},"auditReady":{"type":"boolean"},"requiredGates":{"type":"array","items":{"type":"string","enum":["evidence_current","check_passing","no_open_remediation","owner_approved","human_signoff"]}},"passedGates":{"type":"array","items":{"type":"string","enum":["evidence_current","check_passing","no_open_remediation","owner_approved","human_signoff"]}},"failedGates":{"type":"array","items":{"type":"string","enum":["evidence_current","check_passing","no_open_remediation","owner_approved","human_signoff"]}},"blocker":{"type":["string","null"]}},"required":["policyKey","frameworkCodes","score","auditReady","requiredGates","passedGates","failedGates","blocker"]},"latestEvidence":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"freshness":{"type":"string","enum":["current","stale","expired","missing"]},"sourceName":{"type":["string","null"]},"collectedAt":{"type":"string","format":"date-time"},"validUntil":{"type":["string","null"],"format":"date-time"}},"required":["id","title","freshness","sourceName","collectedAt","validUntil"]},"openTasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"priority":{"type":"string","enum":["low","medium","high","critical"]},"dueAt":{"type":"string","format":"date-time"}},"required":["id","title","priority","dueAt"]}}},"required":["tenantControlId","controlCode","controlTitle","domain","ownerUserId","ownerRole","status","evidenceFreshness","latestResultStatus","auditReady","blocker","readiness","latestEvidence","openTasks"]}}},"required":["generatedAt","summary","items"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework/audit-pack":{"get":{"tags":["controls","evidence"],"summary":"Generate a JSON audit-readiness export pack for controls and evidence","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:read"],"responses":{"200":{"description":"Generate a JSON audit-readiness export pack for controls and evidence","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"packType":{"type":"string","enum":["control_audit_pack"]},"generatedAt":{"type":"string","format":"date-time"},"tenantId":{"type":"string","format":"uuid"},"summary":{"type":"object","properties":{"readinessScore":{"type":"integer"},"totalControls":{"type":"integer"},"acceptedControls":{"type":"integer"},"openEvidenceRequests":{"type":"integer"},"overdueEvidenceRequests":{"type":"integer"},"failingControls":{"type":"integer"},"criticalMonitoringSignals":{"type":"integer"},"openWorkflowTasks":{"type":"integer"},"traceCoverage":{"type":"integer"},"auditReadyControls":{"type":"integer"},"controlsBlockedByEvidence":{"type":"integer"},"controlsBlockedByRemediation":{"type":"integer"},"controlsBlockedByHumanReview":{"type":"integer"}},"required":["readinessScore","totalControls","acceptedControls","openEvidenceRequests","overdueEvidenceRequests","failingControls","criticalMonitoringSignals","openWorkflowTasks","traceCoverage","auditReadyControls","controlsBlockedByEvidence","controlsBlockedByRemediation","controlsBlockedByHumanReview"]},"traceSummary":{"type":"object","properties":{"totalControls":{"type":"integer"},"tracedControls":{"type":"integer"},"traceCoverage":{"type":"integer"},"auditReadyControls":{"type":"integer"},"controlsBlockedByEvidence":{"type":"integer"},"controlsBlockedByRemediation":{"type":"integer"},"controlsBlockedByHumanReview":{"type":"integer"}},"required":["totalControls","tracedControls","traceCoverage","auditReadyControls","controlsBlockedByEvidence","controlsBlockedByRemediation","controlsBlockedByHumanReview"]},"controlTraces":{"type":"array","items":{"type":"object","properties":{"tenantControlId":{"type":"string","format":"uuid"},"controlCode":{"type":"string"},"auditReady":{"type":"boolean"},"pendingActions":{"type":"array","items":{"type":"string"}},"sourceRunIds":{"type":"array","items":{"type":"string"}},"evidenceItemIds":{"type":"array","items":{"type":"string","format":"uuid"}},"auditEventHashes":{"type":"array","items":{"type":"string"}},"timelineEvents":{"type":"integer"}},"required":["tenantControlId","controlCode","auditReady","pendingActions","sourceRunIds","evidenceItemIds","auditEventHashes","timelineEvents"]}},"claimBoundary":{"type":"object","properties":{"allowedClaims":{"type":"array","items":{"type":"string"}},"prohibitedClaims":{"type":"array","items":{"type":"string"}}},"required":["allowedClaims","prohibitedClaims"]},"exportWarnings":{"type":"array","items":{"type":"string"}},"sections":{"type":"object","properties":{"readiness":{"type":"object","properties":{"score":{"type":"integer"},"totalControls":{"type":"integer"},"acceptedControls":{"type":"integer"},"openEvidenceRequests":{"type":"integer"},"overdueEvidenceRequests":{"type":"integer"},"frameworkReadiness":{"type":"object","additionalProperties":{"type":"object","properties":{"total":{"type":"integer"},"accepted":{"type":"integer"},"submitted":{"type":"integer"},"open":{"type":"integer"},"overdue":{"type":"integer"},"score":{"type":"integer"}},"required":["total","accepted","submitted","open","overdue","score"]}},"domainReadiness":{"type":"object","additionalProperties":{"type":"object","properties":{"total":{"type":"integer"},"accepted":{"type":"integer"},"submitted":{"type":"integer"},"open":{"type":"integer"},"overdue":{"type":"integer"},"score":{"type":"integer"}},"required":["total","accepted","submitted","open","overdue","score"]}}},"required":["score","totalControls","acceptedControls","openEvidenceRequests","overdueEvidenceRequests","frameworkReadiness","domainReadiness"]},"monitoring":{"type":"object","properties":{"monitoredControls":{"type":"integer"},"failingControls":{"type":"integer"},"staleEvidenceControls":{"type":"integer"},"overdueEvidenceRequests":{"type":"integer"},"dueTests":{"type":"integer"},"openWorkflowTasks":{"type":"integer"},"criticalWorkflowTasks":{"type":"integer"},"lastSignalAt":{"type":["string","null"],"format":"date-time"},"attentionItems":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["failing_check","stale_evidence","overdue_evidence","due_test","critical_task"]},"severity":{"type":"string","enum":["info","warning","critical"]},"title":{"type":"string"},"detail":{"type":"string"},"controlId":{"type":["string","null"],"format":"uuid"},"controlCode":{"type":["string","null"]},"targetHref":{"type":"string"},"detectedAt":{"type":"string","format":"date-time"}},"required":["id","kind","severity","title","detail","controlId","controlCode","targetHref","detectedAt"]}}},"required":["monitoredControls","failingControls","staleEvidenceControls","overdueEvidenceRequests","dueTests","openWorkflowTasks","criticalWorkflowTasks","lastSignalAt","attentionItems"]},"controls":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"controlId":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"domain":{"type":"string"},"status":{"type":"string","enum":["not_started","in_progress","evidence_requested","evidence_submitted","implemented","needs_review","accepted","overdue","not_applicable","excepted"]},"cadence":{"type":"string","enum":["monthly","quarterly","semi_annual","annual","event_driven"]},"ownerUserId":{"type":["string","null"],"format":"uuid"},"evidenceFreshness":{"type":"string","enum":["current","stale","expired","missing"]},"latestResultStatus":{"type":["string","null"],"enum":["pass","fail","warning","manual","unknown"]},"lastTestedAt":{"type":["string","null"],"format":"date-time"},"nextReviewAt":{"type":["string","null"],"format":"date-time"},"mappedFrameworks":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"requirements":{"type":"array","items":{"type":"string"}}},"required":["code","name","requirements"]}},"evidenceCount":{"type":"integer"},"testCount":{"type":"integer"},"resultCount":{"type":"integer"}},"required":["id","controlId","code","title","description","domain","status","cadence","ownerUserId","evidenceFreshness","latestResultStatus","lastTestedAt","nextReviewAt","mappedFrameworks","evidenceCount","testCount","resultCount"]}},"evidenceRequests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantControlId":{"type":"string","format":"uuid"},"evidenceRequirementId":{"type":"string","format":"uuid"},"evidenceItemId":{"type":["string","null"],"format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"},"artifactType":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"acceptanceCriteria":{"type":"string"},"status":{"type":"string","enum":["open","submitted","needs_changes","accepted","rejected","cancelled","overdue"]},"dueDate":{"type":"string","format":"date-time"},"submittedAt":{"type":["string","null"],"format":"date-time"},"reviewedAt":{"type":["string","null"],"format":"date-time"},"reviewNote":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","tenantControlId","evidenceRequirementId","evidenceItemId","controlCode","controlTitle","artifactType","title","description","acceptanceCriteria","status","dueDate","submittedAt","reviewedAt","reviewNote","createdAt"]}},"workflowTasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantControlId":{"type":"string","format":"uuid"},"evidenceRequestId":{"type":["string","null"],"format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"},"kind":{"type":"string","enum":["evidence_overdue","owner_assignment","reviewer_followup","remediation"]},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["open","in_progress","completed","waived"]},"priority":{"type":"string","enum":["low","medium","high","critical"]},"assignedUserId":{"type":["string","null"],"format":"uuid"},"assignedRole":{"type":["string","null"]},"dueAt":{"type":"string","format":"date-time"},"escalationLevel":{"type":"integer"},"escalatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"completionNote":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","tenantControlId","evidenceRequestId","controlCode","controlTitle","kind","title","description","status","priority","assignedUserId","assignedRole","dueAt","escalationLevel","escalatedAt","completedAt","completionNote","createdAt"]}}},"required":["readiness","monitoring","controls","evidenceRequests","workflowTasks"]},"disclaimer":{"type":"string"}},"required":["packType","generatedAt","tenantId","summary","traceSummary","controlTraces","claimBoundary","exportWarnings","sections","disclaimer"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework/auditor-workspace":{"get":{"tags":["controls","evidence"],"summary":"Get read-only auditor workspace review surface","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:read"],"responses":{"200":{"description":"Get read-only auditor workspace review surface","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"mode":{"type":"string","enum":["read_only"]},"generatedAt":{"type":"string","format":"date-time"},"permissions":{"type":"object","properties":{"canCreate":{"type":"boolean","enum":[false]},"canUpdate":{"type":"boolean","enum":[false]},"canDelete":{"type":"boolean","enum":[false]},"canExport":{"type":"boolean","enum":[true]}},"required":["canCreate","canUpdate","canDelete","canExport"]},"summary":{"type":"object","properties":{"totalControls":{"type":"integer"},"auditReadyControls":{"type":"integer"},"blockedControls":{"type":"integer"},"evidenceInventoryItems":{"type":"integer"},"approvalBlockingOpen":{"type":"integer"},"readyForAuditorReview":{"type":"boolean"}},"required":["totalControls","auditReadyControls","blockedControls","evidenceInventoryItems","approvalBlockingOpen","readyForAuditorReview"]},"controls":{"type":"array","items":{"type":"object","properties":{"tenantControlId":{"type":"string","format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"},"domain":{"type":"string"},"ownerUserId":{"type":["string","null"],"format":"uuid"},"ownerRole":{"type":["string","null"]},"status":{"type":"string","enum":["not_started","in_progress","evidence_requested","evidence_submitted","implemented","needs_review","accepted","overdue","not_applicable","excepted"]},"evidenceFreshness":{"type":"string","enum":["current","stale","expired","missing"]},"latestResultStatus":{"type":["string","null"],"enum":["pass","fail","warning","manual","unknown"]},"auditReady":{"type":"boolean"},"blocker":{"type":["string","null"]},"readiness":{"type":"object","properties":{"policyKey":{"type":"string","enum":["strict_assurance","standard_assurance"]},"frameworkCodes":{"type":"array","items":{"type":"string"}},"score":{"type":"integer","minimum":0,"maximum":100},"auditReady":{"type":"boolean"},"requiredGates":{"type":"array","items":{"type":"string","enum":["evidence_current","check_passing","no_open_remediation","owner_approved","human_signoff"]}},"passedGates":{"type":"array","items":{"type":"string","enum":["evidence_current","check_passing","no_open_remediation","owner_approved","human_signoff"]}},"failedGates":{"type":"array","items":{"type":"string","enum":["evidence_current","check_passing","no_open_remediation","owner_approved","human_signoff"]}},"blocker":{"type":["string","null"]}},"required":["policyKey","frameworkCodes","score","auditReady","requiredGates","passedGates","failedGates","blocker"]},"latestEvidence":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"freshness":{"type":"string","enum":["current","stale","expired","missing"]},"sourceName":{"type":["string","null"]},"collectedAt":{"type":"string","format":"date-time"},"validUntil":{"type":["string","null"],"format":"date-time"}},"required":["id","title","freshness","sourceName","collectedAt","validUntil"]},"openTasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"priority":{"type":"string","enum":["low","medium","high","critical"]},"dueAt":{"type":"string","format":"date-time"}},"required":["id","title","priority","dueAt"]}}},"required":["tenantControlId","controlCode","controlTitle","domain","ownerUserId","ownerRole","status","evidenceFreshness","latestResultStatus","auditReady","blocker","readiness","latestEvidence","openTasks"]}},"blockers":{"type":"array","items":{"type":"object","properties":{"tenantControlId":{"type":"string","format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"},"blocker":{"type":"string"}},"required":["tenantControlId","controlCode","controlTitle","blocker"]}},"approvals":{"type":"object","properties":{"packType":{"type":"string","enum":["control_audit_pack"]},"tenantId":{"type":"string","format":"uuid"},"generatedAt":{"type":"string","format":"date-time"},"summary":{"type":"object","properties":{"totalRequired":{"type":"integer"},"approved":{"type":"integer"},"blockingOpen":{"type":"integer"},"readyForAuditorReview":{"type":"boolean"}},"required":["totalRequired","approved","blockingOpen","readyForAuditorReview"]},"requirements":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"role":{"type":"string","enum":["management","dpo","security_owner","legal","auditor"]},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["required","approved"]},"blocking":{"type":"boolean"},"approvedBy":{"type":["string","null"]},"approvedAt":{"type":["string","null"],"format":"date-time"},"note":{"type":["string","null"]}},"required":["id","role","title","description","status","blocking","approvedBy","approvedAt","note"]}},"disclaimer":{"type":"string"}},"required":["packType","tenantId","generatedAt","summary","requirements","disclaimer"]},"exports":{"type":"object","properties":{"jsonPackAvailable":{"type":"boolean","enum":[true]},"pdfPackAvailable":{"type":"boolean","enum":[true]},"traceCoverage":{"type":"integer"},"warnings":{"type":"array","items":{"type":"string"}}},"required":["jsonPackAvailable","pdfPackAvailable","traceCoverage","warnings"]},"disclaimer":{"type":"string"}},"required":["mode","generatedAt","permissions","summary","controls","blockers","approvals","exports","disclaimer"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework/audit-pack/export":{"post":{"tags":["controls","evidence"],"summary":"Generate a downloadable JSON or PDF audit-readiness pack","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["reports:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"format":{"type":"string","enum":["json","pdf"],"default":"pdf"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Generate a downloadable JSON or PDF audit-readiness pack","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"filename":{"type":"string"},"contentType":{"type":"string","enum":["application/json","application/pdf"]},"generatedAt":{"type":"string","format":"date-time"},"base64":{"type":"string"},"summary":{"type":"object","properties":{"totalControls":{"type":"integer"},"auditReadyControls":{"type":"integer"},"evidenceInventoryItems":{"type":"integer"},"blockedControls":{"type":"integer"},"approvalGates":{"type":"integer"},"blockingApprovals":{"type":"integer"}},"required":["totalControls","auditReadyControls","evidenceInventoryItems","blockedControls","approvalGates","blockingApprovals"]}},"required":["filename","contentType","generatedAt","base64","summary"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `reports:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/control-framework/approval-layer":{"get":{"tags":["controls","evidence"],"summary":"List human approval gates for the current control audit pack","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:read"],"responses":{"200":{"description":"List human approval gates for the current control audit pack","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"packType":{"type":"string","enum":["control_audit_pack"]},"tenantId":{"type":"string","format":"uuid"},"generatedAt":{"type":"string","format":"date-time"},"summary":{"type":"object","properties":{"totalRequired":{"type":"integer"},"approved":{"type":"integer"},"blockingOpen":{"type":"integer"},"readyForAuditorReview":{"type":"boolean"}},"required":["totalRequired","approved","blockingOpen","readyForAuditorReview"]},"requirements":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"role":{"type":"string","enum":["management","dpo","security_owner","legal","auditor"]},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["required","approved"]},"blocking":{"type":"boolean"},"approvedBy":{"type":["string","null"]},"approvedAt":{"type":["string","null"],"format":"date-time"},"note":{"type":["string","null"]}},"required":["id","role","title","description","status","blocking","approvedBy","approvedAt","note"]}},"disclaimer":{"type":"string"}},"required":["packType","tenantId","generatedAt","summary","requirements","disclaimer"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework/audit-integrity":{"get":{"tags":["controls","evidence"],"summary":"Verify tamper-evident integrity of the control audit event chain","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:read"],"responses":{"200":{"description":"Verify tamper-evident integrity of the control audit event chain","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"summary":{"type":"object","properties":{"totalEvents":{"type":"integer"},"sealedEvents":{"type":"integer"},"unsealedEvents":{"type":"integer"},"brokenEvents":{"type":"integer"},"headHash":{"type":["string","null"]},"verified":{"type":"boolean"}},"required":["totalEvents","sealedEvents","unsealedEvents","brokenEvents","headHash","verified"]},"events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"actorUserId":{"type":["string","null"],"format":"uuid"},"objectType":{"type":"string","enum":["tenant_control","evidence_request","evidence_item","workflow_task","control_export"]},"objectId":{"type":"string"},"action":{"type":"string"},"previousValue":{},"newValue":{},"requestMetadata":{},"createdAt":{"type":"string","format":"date-time"},"sequence":{"type":"integer"},"previousHash":{"type":["string","null"]},"eventHash":{"type":["string","null"]},"expectedHash":{"type":"string"},"integrityStatus":{"type":"string","enum":["sealed","unsealed","broken"]}},"required":["id","tenantId","actorUserId","objectType","objectId","action","createdAt","sequence","previousHash","eventHash","expectedHash","integrityStatus"]}},"disclaimer":{"type":"string"}},"required":["summary","events","disclaimer"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework/approval-layer/approvals":{"post":{"tags":["controls","evidence"],"summary":"Record a human approval for the current control audit pack","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["management","dpo","security_owner","legal","auditor"]},"note":{"type":"string","maxLength":1000}},"required":["role"],"additionalProperties":false}}}},"responses":{"200":{"description":"Record a human approval for the current control audit pack","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"packType":{"type":"string","enum":["control_audit_pack"]},"tenantId":{"type":"string","format":"uuid"},"generatedAt":{"type":"string","format":"date-time"},"summary":{"type":"object","properties":{"totalRequired":{"type":"integer"},"approved":{"type":"integer"},"blockingOpen":{"type":"integer"},"readyForAuditorReview":{"type":"boolean"}},"required":["totalRequired","approved","blockingOpen","readyForAuditorReview"]},"requirements":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"role":{"type":"string","enum":["management","dpo","security_owner","legal","auditor"]},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["required","approved"]},"blocking":{"type":"boolean"},"approvedBy":{"type":["string","null"]},"approvedAt":{"type":["string","null"],"format":"date-time"},"note":{"type":["string","null"]}},"required":["id","role","title","description","status","blocking","approvedBy","approvedAt","note"]}},"disclaimer":{"type":"string"}},"required":["packType","tenantId","generatedAt","summary","requirements","disclaimer"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/control-framework/evidence-requests":{"get":{"tags":["controls","evidence"],"summary":"List generated evidence requests for tenant controls","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["evidence:read"],"responses":{"200":{"description":"List generated evidence requests for tenant controls","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantControlId":{"type":"string","format":"uuid"},"evidenceRequirementId":{"type":"string","format":"uuid"},"evidenceItemId":{"type":["string","null"],"format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"},"artifactType":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"acceptanceCriteria":{"type":"string"},"status":{"type":"string","enum":["open","submitted","needs_changes","accepted","rejected","cancelled","overdue"]},"dueDate":{"type":"string","format":"date-time"},"submittedAt":{"type":["string","null"],"format":"date-time"},"reviewedAt":{"type":["string","null"],"format":"date-time"},"reviewNote":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","tenantControlId","evidenceRequirementId","evidenceItemId","controlCode","controlTitle","artifactType","title","description","acceptanceCriteria","status","dueDate","submittedAt","reviewedAt","reviewNote","createdAt"]}}},"required":["items"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `evidence:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework/evidence-requests/generate":{"post":{"tags":["controls","evidence"],"summary":"Generate evidence requests from active control requirements","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["evidence:write"],"responses":{"200":{"description":"Generate evidence requests from active control requirements","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"created":{"type":"integer"},"existing":{"type":"integer"}},"required":["created","existing"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `evidence:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/control-framework/workflow-tasks":{"get":{"tags":["controls","evidence"],"summary":"List workflow tasks generated from control and evidence SLAs","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:read"],"responses":{"200":{"description":"List workflow tasks generated from control and evidence SLAs","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantControlId":{"type":"string","format":"uuid"},"evidenceRequestId":{"type":["string","null"],"format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"},"kind":{"type":"string","enum":["evidence_overdue","owner_assignment","reviewer_followup","remediation"]},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["open","in_progress","completed","waived"]},"priority":{"type":"string","enum":["low","medium","high","critical"]},"assignedUserId":{"type":["string","null"],"format":"uuid"},"assignedRole":{"type":["string","null"]},"dueAt":{"type":"string","format":"date-time"},"escalationLevel":{"type":"integer"},"escalatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"completionNote":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","tenantControlId","evidenceRequestId","controlCode","controlTitle","kind","title","description","status","priority","assignedUserId","assignedRole","dueAt","escalationLevel","escalatedAt","completedAt","completionNote","createdAt"]}}},"required":["items"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework/workflow-tasks/enforce":{"post":{"tags":["controls","evidence"],"summary":"Enforce control workflow SLAs and generate overdue/escalation tasks","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:write"],"responses":{"200":{"description":"Enforce control workflow SLAs and generate overdue/escalation tasks","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"overdueRequests":{"type":"integer"},"ownerAssignmentGaps":{"type":"integer"},"tasksCreated":{"type":"integer"},"tasksUpdated":{"type":"integer"},"evidenceItemsScanned":{"type":"integer"},"evidenceItemsUpdated":{"type":"integer"},"controlsUpdated":{"type":"integer"},"freshnessTasksCreated":{"type":"integer"},"freshnessTasksUpdated":{"type":"integer"},"freshnessTasksResolved":{"type":"integer"}},"required":["overdueRequests","ownerAssignmentGaps","tasksCreated","tasksUpdated","evidenceItemsScanned","evidenceItemsUpdated","controlsUpdated","freshnessTasksCreated","freshnessTasksUpdated","freshnessTasksResolved"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/control-framework/workflow-tasks/:taskId/complete":{"post":{"tags":["controls","evidence"],"summary":"Complete a control workflow task","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:write"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"taskId","in":"path"},{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"completionNote":{"type":"string","maxLength":1000}},"additionalProperties":false}}}},"responses":{"200":{"description":"Complete a control workflow task","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantControlId":{"type":"string","format":"uuid"},"evidenceRequestId":{"type":["string","null"],"format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"},"kind":{"type":"string","enum":["evidence_overdue","owner_assignment","reviewer_followup","remediation"]},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["open","in_progress","completed","waived"]},"priority":{"type":"string","enum":["low","medium","high","critical"]},"assignedUserId":{"type":["string","null"],"format":"uuid"},"assignedRole":{"type":["string","null"]},"dueAt":{"type":"string","format":"date-time"},"escalationLevel":{"type":"integer"},"escalatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"completionNote":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","tenantControlId","evidenceRequestId","controlCode","controlTitle","kind","title","description","status","priority","assignedUserId","assignedRole","dueAt","escalationLevel","escalatedAt","completedAt","completionNote","createdAt"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","x-asiri-idempotency":"required"}},"/v1/control-framework/evidence":{"get":{"tags":["controls","evidence"],"summary":"List tenant evidence items","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["evidence:read"],"responses":{"200":{"description":"List tenant evidence items","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":["string","null"]},"type":{"type":"string","enum":["policy","screenshot","report","export","attestation","configuration","ticket","log","other"]},"freshness":{"type":"string","enum":["current","stale","expired","missing"]},"sourceName":{"type":["string","null"]},"sourceType":{"type":["string","null"],"enum":["manual","integration","system_import","report","upload"]},"controlCode":{"type":["string","null"]},"controlTitle":{"type":["string","null"]},"controlMapping":{"type":["object","null"],"properties":{"tenantControlId":{"type":"string","format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"}},"required":["tenantControlId","controlCode","controlTitle"]},"externalUrl":{"type":["string","null"],"format":"uri"},"observedAt":{"type":["string","null"],"format":"date-time"},"validUntil":{"type":["string","null"],"format":"date-time"},"collectedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"apiSubmissionId":{"type":["string","null"]},"submittedByApiKeyPrefix":{"type":["string","null"]},"payloadHash":{"type":["string","null"]},"redactionVersion":{"type":["string","null"]},"redactedFields":{"type":"array","items":{"type":"string"}},"classification":{"type":"string"},"containsPersonalData":{"type":"boolean"},"reviewStatus":{"type":"string"},"exportWarning":{"type":["string","null"]}},"required":["id","title","description","type","freshness","sourceName","controlCode","controlTitle","externalUrl","observedAt","validUntil","collectedAt","createdAt"]}}},"required":["items"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `evidence:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."},"post":{"tags":["controls","evidence"],"summary":"Add an evidence item to a control","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["evidence:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tenantControlId":{"type":"string","format":"uuid"},"sourceId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":1,"maxLength":180},"description":{"type":"string","maxLength":1000},"type":{"type":"string","enum":["policy","screenshot","report","export","attestation","configuration","ticket","log","other"]},"externalUrl":{"type":"string","format":"uri"},"observedAt":{"type":"string","format":"date-time"},"validUntil":{"type":"string","format":"date-time"}},"required":["title","type"],"additionalProperties":false}}}},"responses":{"201":{"description":"Add an evidence item to a control","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":["string","null"]},"type":{"type":"string","enum":["policy","screenshot","report","export","attestation","configuration","ticket","log","other"]},"freshness":{"type":"string","enum":["current","stale","expired","missing"]},"sourceName":{"type":["string","null"]},"sourceType":{"type":["string","null"],"enum":["manual","integration","system_import","report","upload"]},"controlCode":{"type":["string","null"]},"controlTitle":{"type":["string","null"]},"controlMapping":{"type":["object","null"],"properties":{"tenantControlId":{"type":"string","format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"}},"required":["tenantControlId","controlCode","controlTitle"]},"externalUrl":{"type":["string","null"],"format":"uri"},"observedAt":{"type":["string","null"],"format":"date-time"},"validUntil":{"type":["string","null"],"format":"date-time"},"collectedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"apiSubmissionId":{"type":["string","null"]},"submittedByApiKeyPrefix":{"type":["string","null"]},"payloadHash":{"type":["string","null"]},"redactionVersion":{"type":["string","null"]},"redactedFields":{"type":"array","items":{"type":"string"}},"classification":{"type":"string"},"containsPersonalData":{"type":"boolean"},"reviewStatus":{"type":"string"},"exportWarning":{"type":["string","null"]}},"required":["id","title","description","type","freshness","sourceName","controlCode","controlTitle","externalUrl","observedAt","validUntil","collectedAt","createdAt"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `evidence:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/control-framework/sources":{"get":{"tags":["controls","evidence"],"summary":"List evidence sources","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["evidence:read"],"responses":{"200":{"description":"List evidence sources","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"sourceType":{"type":"string","enum":["manual","integration","system_import","report","upload"]},"providerKey":{"type":["string","null"]},"status":{"type":"string"},"lastSyncAt":{"type":["string","null"],"format":"date-time"},"nextSyncAt":{"type":["string","null"],"format":"date-time"},"itemCount":{"type":"integer"}},"required":["id","name","sourceType","providerKey","status","lastSyncAt","nextSyncAt","itemCount"]}}},"required":["items"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `evidence:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."},"post":{"tags":["controls","evidence"],"summary":"Create an evidence source","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["evidence:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":160},"sourceType":{"type":"string","enum":["manual","integration","system_import","report","upload"]},"providerKey":{"type":"string","minLength":1,"maxLength":80},"description":{"type":"string","maxLength":500}},"required":["name","sourceType"],"additionalProperties":false}}}},"responses":{"201":{"description":"Create an evidence source","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"sourceType":{"type":"string","enum":["manual","integration","system_import","report","upload"]},"providerKey":{"type":["string","null"]},"status":{"type":"string"},"lastSyncAt":{"type":["string","null"],"format":"date-time"},"nextSyncAt":{"type":["string","null"],"format":"date-time"},"itemCount":{"type":"integer"}},"required":["id","name","sourceType","providerKey","status","lastSyncAt","nextSyncAt","itemCount"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `evidence:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/control-framework/evidence-requests/:evidenceRequestId/submit":{"post":{"tags":["controls","evidence"],"summary":"Submit an evidence item for an evidence request","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["evidence:write"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"evidenceRequestId","in":"path"},{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"evidenceItemId":{"type":"string","format":"uuid"}},"required":["evidenceItemId"],"additionalProperties":false}}}},"responses":{"200":{"description":"Submit an evidence item for an evidence request","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantControlId":{"type":"string","format":"uuid"},"evidenceRequirementId":{"type":"string","format":"uuid"},"evidenceItemId":{"type":["string","null"],"format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"},"artifactType":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"acceptanceCriteria":{"type":"string"},"status":{"type":"string","enum":["open","submitted","needs_changes","accepted","rejected","cancelled","overdue"]},"dueDate":{"type":"string","format":"date-time"},"submittedAt":{"type":["string","null"],"format":"date-time"},"reviewedAt":{"type":["string","null"],"format":"date-time"},"reviewNote":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","tenantControlId","evidenceRequirementId","evidenceItemId","controlCode","controlTitle","artifactType","title","description","acceptanceCriteria","status","dueDate","submittedAt","reviewedAt","reviewNote","createdAt"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `evidence:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","x-asiri-idempotency":"required"}},"/v1/control-framework/evidence-requests/:evidenceRequestId/review":{"post":{"tags":["controls","evidence"],"summary":"Review a submitted evidence request","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["evidence:write"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"evidenceRequestId","in":"path"},{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["accepted","needs_changes","rejected"]},"reviewNote":{"type":"string","maxLength":1000}},"required":["status"],"additionalProperties":false}}}},"responses":{"200":{"description":"Review a submitted evidence request","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantControlId":{"type":"string","format":"uuid"},"evidenceRequirementId":{"type":"string","format":"uuid"},"evidenceItemId":{"type":["string","null"],"format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"},"artifactType":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"acceptanceCriteria":{"type":"string"},"status":{"type":"string","enum":["open","submitted","needs_changes","accepted","rejected","cancelled","overdue"]},"dueDate":{"type":"string","format":"date-time"},"submittedAt":{"type":["string","null"],"format":"date-time"},"reviewedAt":{"type":["string","null"],"format":"date-time"},"reviewNote":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","tenantControlId","evidenceRequirementId","evidenceItemId","controlCode","controlTitle","artifactType","title","description","acceptanceCriteria","status","dueDate","submittedAt","reviewedAt","reviewNote","createdAt"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `evidence:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","x-asiri-idempotency":"required"}},"/v1/control-framework/results":{"post":{"tags":["controls","evidence"],"summary":"Record a control test result","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tenantControlId":{"type":"string","format":"uuid"},"testId":{"type":"string","format":"uuid"},"evidenceItemId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pass","fail","warning","manual","unknown"]},"message":{"type":"string","maxLength":1000},"failureReason":{"type":"string","maxLength":1000},"remediationGuidance":{"type":"string","maxLength":1000}},"required":["tenantControlId","status"],"additionalProperties":false}}}},"responses":{"201":{"description":"Record a control test result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pass","fail","warning","manual","unknown"]},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"failureReason":{"type":["string","null"]},"remediationGuidance":{"type":["string","null"]}},"required":["id","status","createdAt","completedAt","failureReason","remediationGuidance"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/control-framework/:tenantControlId/intelligence":{"get":{"tags":["controls","evidence"],"summary":"Get cited regulatory intelligence guidance for a tenant control","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:read"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"tenantControlId","in":"path"}],"responses":{"200":{"description":"Get cited regulatory intelligence guidance for a tenant control","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"tenantControlId":{"type":"string","format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"},"riskLevel":{"type":["string","null"],"enum":["low","medium","high","critical"]},"ownerRole":{"type":["string","null"]},"whyItMatters":{"type":"string"},"remediationGuidance":{"type":"string"},"evidenceExpectations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"artifactType":{"type":"string"},"description":{"type":"string"},"acceptanceCriteria":{"type":"string"},"defaultDueDays":{"type":"integer"},"requestStatus":{"type":["string","null"],"enum":["open","submitted","needs_changes","accepted","rejected","cancelled","overdue"]},"dueDate":{"type":["string","null"],"format":"date-time"}},"required":["id","title","artifactType","description","acceptanceCriteria","defaultDueDays","requestStatus","dueDate"]}},"frameworkMappings":{"type":"array","items":{"type":"object","properties":{"frameworkCode":{"type":"string"},"frameworkName":{"type":"string"},"requirementCode":{"type":"string"},"requirementTitle":{"type":"string"},"requirementDescription":{"type":"string"},"coverage":{"type":"string","enum":["primary","supporting","inherited"]},"rationale":{"type":"string"}},"required":["frameworkCode","frameworkName","requirementCode","requirementTitle","requirementDescription","coverage","rationale"]}},"claimBoundary":{"type":"object","properties":{"controlBoundary":{"type":["string","null"]},"allowedClaims":{"type":"array","items":{"type":"string"}},"prohibitedClaims":{"type":"array","items":{"type":"string"}}},"required":["controlBoundary","allowedClaims","prohibitedClaims"]},"humanReviewRequired":{"type":"boolean","enum":[true]},"disclaimer":{"type":"string"}},"required":["tenantControlId","controlCode","controlTitle","riskLevel","ownerRole","whyItMatters","remediationGuidance","evidenceExpectations","frameworkMappings","claimBoundary","humanReviewRequired","disclaimer"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework/:tenantControlId/audit-trace":{"get":{"tags":["controls","evidence"],"summary":"Get audit-readiness traceability for a tenant control","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:read"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"tenantControlId","in":"path"}],"responses":{"200":{"description":"Get audit-readiness traceability for a tenant control","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"tenantControlId":{"type":"string","format":"uuid"},"controlCode":{"type":"string"},"generatedAt":{"type":"string","format":"date-time"},"summary":{"type":"object","properties":{"auditReady":{"type":"boolean"},"evidenceCurrent":{"type":"boolean"},"latestCheckPassing":{"type":"boolean"},"noOpenRemediation":{"type":"boolean"},"acceptedOrImplemented":{"type":"boolean"},"timelineEvents":{"type":"integer"},"sourceRunIds":{"type":"array","items":{"type":"string"}},"evidenceItemIds":{"type":"array","items":{"type":"string","format":"uuid"}},"auditEventHashes":{"type":"array","items":{"type":"string"}}},"required":["auditReady","evidenceCurrent","latestCheckPassing","noOpenRemediation","acceptedOrImplemented","timelineEvents","sourceRunIds","evidenceItemIds","auditEventHashes"]},"whyAuditReady":{"type":"array","items":{"type":"string"}},"pendingActions":{"type":"array","items":{"type":"string"}},"timeline":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["connector_run","evidence_collected","control_status_changed","remediation_opened","remediation_completed","human_approval","export_generated","audit_event"]},"title":{"type":"string"},"detail":{"type":"string"},"occurredAt":{"type":"string","format":"date-time"},"actorUserId":{"type":["string","null"],"format":"uuid"},"objectType":{"type":"string","enum":["tenant_control","evidence_request","evidence_item","workflow_task","control_export","control_test_result","connector_run"]},"objectId":{"type":"string"},"auditEventId":{"type":["string","null"],"format":"uuid"},"auditEventHash":{"type":["string","null"]},"sourceRunId":{"type":["string","null"]},"evidenceItemId":{"type":["string","null"],"format":"uuid"}},"required":["id","kind","title","detail","occurredAt","actorUserId","objectType","objectId","auditEventId","auditEventHash","sourceRunId","evidenceItemId"]}},"disclaimer":{"type":"string"}},"required":["tenantControlId","controlCode","generatedAt","summary","whyAuditReady","pendingActions","timeline","disclaimer"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/control-framework/:tenantControlId":{"get":{"tags":["controls","evidence"],"summary":"Get a control detail view with evidence, sources, and result history","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["controls:read"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"tenantControlId","in":"path"}],"responses":{"200":{"description":"Get a control detail view with evidence, sources, and result history","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"controlId":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"domain":{"type":"string"},"status":{"type":"string","enum":["not_started","in_progress","evidence_requested","evidence_submitted","implemented","needs_review","accepted","overdue","not_applicable","excepted"]},"cadence":{"type":"string","enum":["monthly","quarterly","semi_annual","annual","event_driven"]},"ownerUserId":{"type":["string","null"],"format":"uuid"},"evidenceFreshness":{"type":"string","enum":["current","stale","expired","missing"]},"latestResultStatus":{"type":["string","null"],"enum":["pass","fail","warning","manual","unknown"]},"lastTestedAt":{"type":["string","null"],"format":"date-time"},"nextReviewAt":{"type":["string","null"],"format":"date-time"},"mappedFrameworks":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"requirements":{"type":"array","items":{"type":"string"}}},"required":["code","name","requirements"]}},"evidenceCount":{"type":"integer"},"testCount":{"type":"integer"},"resultCount":{"type":"integer"},"implementationGuidance":{"type":["string","null"]},"implementationNotes":{"type":["string","null"]},"exceptionReason":{"type":["string","null"]},"lastReviewedAt":{"type":["string","null"],"format":"date-time"},"evidence":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":["string","null"]},"type":{"type":"string","enum":["policy","screenshot","report","export","attestation","configuration","ticket","log","other"]},"freshness":{"type":"string","enum":["current","stale","expired","missing"]},"sourceName":{"type":["string","null"]},"sourceType":{"type":["string","null"],"enum":["manual","integration","system_import","report","upload"]},"controlCode":{"type":["string","null"]},"controlTitle":{"type":["string","null"]},"controlMapping":{"type":["object","null"],"properties":{"tenantControlId":{"type":"string","format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"}},"required":["tenantControlId","controlCode","controlTitle"]},"externalUrl":{"type":["string","null"],"format":"uri"},"observedAt":{"type":["string","null"],"format":"date-time"},"validUntil":{"type":["string","null"],"format":"date-time"},"collectedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"apiSubmissionId":{"type":["string","null"]},"submittedByApiKeyPrefix":{"type":["string","null"]},"payloadHash":{"type":["string","null"]},"redactionVersion":{"type":["string","null"]},"redactedFields":{"type":"array","items":{"type":"string"}},"classification":{"type":"string"},"containsPersonalData":{"type":"boolean"},"reviewStatus":{"type":"string"},"exportWarning":{"type":["string","null"]}},"required":["id","title","description","type","freshness","sourceName","controlCode","controlTitle","externalUrl","observedAt","validUntil","collectedAt","createdAt"]}},"sources":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"sourceType":{"type":"string","enum":["manual","integration","system_import","report","upload"]},"providerKey":{"type":["string","null"]},"status":{"type":"string"},"lastSyncAt":{"type":["string","null"],"format":"date-time"},"nextSyncAt":{"type":["string","null"],"format":"date-time"},"itemCount":{"type":"integer"}},"required":["id","name","sourceType","providerKey","status","lastSyncAt","nextSyncAt","itemCount"]}},"tests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"key":{"type":"string"},"title":{"type":"string"},"description":{"type":["string","null"]},"kind":{"type":"string","enum":["manual","automated","connector_query","document_check"]},"cadence":{"type":"string","enum":["monthly","quarterly","semi_annual","annual","event_driven"]},"isActive":{"type":"boolean"},"lastRunAt":{"type":["string","null"],"format":"date-time"},"nextRunAt":{"type":["string","null"],"format":"date-time"},"isDue":{"type":"boolean"},"latestStatus":{"type":"string","enum":["pass","fail","warning","manual","unknown"]},"latestResultAt":{"type":["string","null"],"format":"date-time"},"failureReason":{"type":["string","null"]},"remediationGuidance":{"type":["string","null"]}},"required":["id","key","title","description","kind","cadence","isActive","lastRunAt","nextRunAt","isDue","latestStatus","latestResultAt","failureReason","remediationGuidance"]}},"results":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"testId":{"type":["string","null"],"format":"uuid"},"evidenceItemId":{"type":["string","null"],"format":"uuid"},"testTitle":{"type":["string","null"]},"evidenceTitle":{"type":["string","null"]},"status":{"type":"string","enum":["pass","fail","warning","manual","unknown"]},"message":{"type":["string","null"]},"failureReason":{"type":["string","null"]},"remediationGuidance":{"type":["string","null"]},"startedAt":{"type":"string","format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","testId","evidenceItemId","testTitle","evidenceTitle","status","message","failureReason","remediationGuidance","startedAt","completedAt","createdAt"]}},"workflowTasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantControlId":{"type":"string","format":"uuid"},"evidenceRequestId":{"type":["string","null"],"format":"uuid"},"controlCode":{"type":"string"},"controlTitle":{"type":"string"},"kind":{"type":"string","enum":["evidence_overdue","owner_assignment","reviewer_followup","remediation"]},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["open","in_progress","completed","waived"]},"priority":{"type":"string","enum":["low","medium","high","critical"]},"assignedUserId":{"type":["string","null"],"format":"uuid"},"assignedRole":{"type":["string","null"]},"dueAt":{"type":"string","format":"date-time"},"escalationLevel":{"type":"integer"},"escalatedAt":{"type":["string","null"],"format":"date-time"},"completedAt":{"type":["string","null"],"format":"date-time"},"completionNote":{"type":["string","null"]},"createdAt":{"type":"string","format":"date-time"}},"required":["id","tenantControlId","evidenceRequestId","controlCode","controlTitle","kind","title","description","status","priority","assignedUserId","assignedRole","dueAt","escalationLevel","escalatedAt","completedAt","completionNote","createdAt"]}},"automationEvents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"provider":{"type":["string","null"]},"runId":{"type":["string","null"]},"previousStatus":{"type":["string","null"]},"nextStatus":{"type":["string","null"]},"latestResultStatus":{"type":["string","null"]},"evidenceFreshness":{"type":["string","null"]},"statusChanged":{"type":"boolean"},"actorUserId":{"type":["string","null"],"format":"uuid"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","provider","runId","previousStatus","nextStatus","latestResultStatus","evidenceFreshness","statusChanged","actorUserId","createdAt"]}}},"required":["id","controlId","code","title","description","domain","status","cadence","ownerUserId","evidenceFreshness","latestResultStatus","lastTestedAt","nextReviewAt","mappedFrameworks","evidenceCount","testCount","resultCount","implementationGuidance","implementationNotes","exceptionReason","lastReviewedAt","evidence","sources","tests","results","workflowTasks","automationEvents"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `controls:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/external/evidence":{"post":{"tags":["external-api","evidence"],"summary":"Submit external evidence into the ASIRI evidence vault","description":"Accepts customer-submitted evidence, normalizes it, redacts raw payload secrets, stores a hash-verifiable vault snapshot, and maps it to controls when possible.\n\nRequired API key scope: `evidence:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["evidence:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"apiSubmissionId":{"type":"string","minLength":3,"maxLength":160},"title":{"type":"string","minLength":2,"maxLength":200},"description":{"type":"string","maxLength":2000},"evidenceType":{"type":"string","enum":["policy","screenshot","report","export","attestation","configuration","ticket","log","other"],"default":"attestation"},"controlIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":120},"maxItems":25,"default":[]},"collectedAt":{"type":"string","format":"date-time"},"observedAt":{"type":"string","format":"date-time"},"validUntil":{"type":"string","format":"date-time"},"externalUrl":{"type":"string","format":"uri"},"classification":{"type":"string","enum":["public","internal","confidential","restricted"],"default":"internal"},"containsPersonalData":{"type":"boolean","default":false},"ownerEmail":{"type":"string","format":"email"},"remediationGuidance":{"type":"string","maxLength":2000},"metadata":{"type":"object","additionalProperties":{}},"rawPayload":{}},"required":["apiSubmissionId","title"],"additionalProperties":false}}}},"responses":{"201":{"description":"Accepts customer-submitted evidence, normalizes it, redacts raw payload secrets, stores a hash-verifiable vault snapshot, and maps it to controls when possible.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"apiSubmissionId":{"type":"string"},"title":{"type":"string"},"type":{"type":"string","enum":["policy","screenshot","report","export","attestation","configuration","ticket","log","other"]},"freshness":{"type":"string","enum":["current","stale","expired","missing"]},"reviewStatus":{"type":"string","enum":["accepted","needs_review","rejected"]},"classification":{"type":"string"},"containsPersonalData":{"type":"boolean"},"sourceName":{"type":"string"},"mappedControls":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"title":{"type":"string"}},"required":["id","code","title"]}},"payloadHash":{"type":["string","null"]},"redactedFields":{"type":"array","items":{"type":"string"}},"duplicate":{"type":"boolean"},"collectedAt":{"type":"string","format":"date-time"},"validUntil":{"type":["string","null"],"format":"date-time"}},"required":["id","apiSubmissionId","title","type","freshness","reviewStatus","classification","containsPersonalData","sourceName","mappedControls","payloadHash","redactedFields","duplicate","collectedAt","validUntil"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/external/consent-events":{"post":{"tags":["external-api"],"summary":"Submit a consent event from a customer website or app","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["consent:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"apiSubmissionId":{"type":"string","minLength":3,"maxLength":160},"noticeId":{"type":"string","format":"uuid"},"subjectRef":{"type":"string","minLength":1,"maxLength":200},"subjectChannel":{"type":"string","enum":["email","phone","subject_id"],"default":"subject_id"},"noticeVersion":{"type":"string","minLength":1,"maxLength":120},"choices":{"type":"object","additionalProperties":{"type":"boolean"}},"capturedAt":{"type":"string","format":"date-time"},"page":{"type":"string","maxLength":500},"ip":{"type":"string","format":"ip"},"userAgent":{"type":"string","maxLength":500},"method":{"type":"string","enum":["banner","modal","inline","checkbox","double_opt_in","verbal_recorded"],"default":"banner"},"rawPayload":{}},"required":["apiSubmissionId","noticeId","subjectRef","noticeVersion","choices"],"additionalProperties":false}}}},"responses":{"201":{"description":"Submit a consent event from a customer website or app","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"apiSubmissionId":{"type":"string"},"reviewStatus":{"type":"string","enum":["accepted","needs_review","rejected"]},"payloadHash":{"type":["string","null"]},"duplicate":{"type":"boolean"}},"required":["id","apiSubmissionId","reviewStatus","payloadHash","duplicate"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `consent:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/external/dsr":{"post":{"tags":["external-api"],"summary":"Submit a data subject request intake from an external form","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["dsr:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"apiSubmissionId":{"type":"string","minLength":3,"maxLength":160},"requestType":{"type":"string","enum":["access","rectification","erasure","portability","restriction","objection","automated","withdrawal"]},"requesterName":{"type":"string","minLength":1,"maxLength":200},"requesterEmail":{"type":"string","format":"email"},"subjectEmail":{"type":"string","format":"email"},"subjectRef":{"type":"string","maxLength":200},"channel":{"type":"string","enum":["portal","email","phone","in_person","post","social","agent"],"default":"portal"},"source":{"type":"string","minLength":1,"maxLength":120},"message":{"type":"string","maxLength":2000},"submittedAt":{"type":"string","format":"date-time"},"receivedAt":{"type":"string","format":"date-time"},"rawPayload":{}},"required":["apiSubmissionId","requestType"],"additionalProperties":false}}}},"responses":{"201":{"description":"Submit a data subject request intake from an external form","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"apiSubmissionId":{"type":"string"},"reviewStatus":{"type":"string","enum":["accepted","needs_review","rejected"]},"payloadHash":{"type":["string","null"]},"duplicate":{"type":"boolean"}},"required":["id","apiSubmissionId","reviewStatus","payloadHash","duplicate"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `dsr:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/external/vendors/{externalVendorId}":{"put":{"tags":["external-api"],"summary":"Sync vendor or subprocessor evidence from an external system","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["vendors:write"],"parameters":[{"schema":{"type":"string","minLength":1,"maxLength":160},"required":true,"name":"externalVendorId","in":"path"},{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"apiSubmissionId":{"type":"string","minLength":3,"maxLength":160},"name":{"type":"string","minLength":1,"maxLength":200},"service":{"type":"string","minLength":1,"maxLength":300},"category":{"type":"string","maxLength":160},"status":{"type":"string","enum":["prospect","onboarding","active","monitoring","suspended","offboarded"],"default":"monitoring"},"criticality":{"type":"string","enum":["low","medium","high","critical"],"default":"medium"},"subprocessor":{"type":"boolean","default":false},"dataCategories":{"type":"array","items":{"type":"string","minLength":1,"maxLength":120},"default":[]},"processesPersonalData":{"type":"boolean","default":false},"country":{"type":"string","maxLength":80},"dpaStatus":{"type":"string","maxLength":80},"reviewedAt":{"type":"string","format":"date-time"},"rawPayload":{}},"required":["name"],"additionalProperties":false}}}},"responses":{"200":{"description":"Sync vendor or subprocessor evidence from an external system","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"apiSubmissionId":{"type":"string"},"reviewStatus":{"type":"string","enum":["accepted","needs_review","rejected"]},"payloadHash":{"type":["string","null"]},"duplicate":{"type":"boolean"}},"required":["id","apiSubmissionId","reviewStatus","payloadHash","duplicate"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `vendors:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","x-asiri-idempotency":"required"}},"/v1/external/incidents":{"post":{"tags":["external-api"],"summary":"Submit incident or breach intake evidence from external tooling","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["incidents:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"apiSubmissionId":{"type":"string","minLength":3,"maxLength":160},"title":{"type":"string","minLength":2,"maxLength":200},"severity":{"type":"string","enum":["low","medium","high","critical"],"default":"medium"},"occurredAt":{"type":"string","format":"date-time"},"detectedAt":{"type":"string","format":"date-time"},"description":{"type":"string","maxLength":2000},"cause":{"type":"string","enum":["external_attack","insider","misconfiguration","lost_device","third_party","physical","other"]},"discovery":{"type":"string","enum":["monitoring","user_report","third_party","audit","media","regulator"]},"attackVector":{"type":"string","enum":["phishing","credential_stuffing","malware","ransomware","sql_injection","social_engineering","physical","unknown"]},"systemsAffected":{"type":"array","items":{"type":"string","minLength":1,"maxLength":160},"default":[]},"geographicScope":{"type":"array","items":{"type":"string","minLength":1,"maxLength":120},"default":[]},"dataTypes":{"type":"array","items":{"type":"string","minLength":1,"maxLength":160},"default":[]},"affected":{"type":"integer","minimum":0},"recordsConfirmed":{"type":"integer","minimum":0},"recordsEstimated":{"type":"integer","minimum":0},"reporterName":{"type":"string","maxLength":160},"reporterContact":{"type":"string","maxLength":240},"containsPersonalData":{"type":"boolean","default":false},"rawPayload":{}},"required":["apiSubmissionId","title"],"additionalProperties":false}}}},"responses":{"201":{"description":"Submit incident or breach intake evidence from external tooling","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"apiSubmissionId":{"type":"string"},"reviewStatus":{"type":"string","enum":["accepted","needs_review","rejected"]},"payloadHash":{"type":["string","null"]},"duplicate":{"type":"boolean"}},"required":["id","apiSubmissionId","reviewStatus","payloadHash","duplicate"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `incidents:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/external/trust-center/status":{"get":{"tags":["external-api"],"summary":"Read Trust Center publication status for customer portals","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["trust-center:read"],"responses":{"200":{"description":"Read Trust Center publication status for customer portals","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"published":{"type":"boolean"},"slug":{"type":["string","null"]},"url":{"type":["string","null"],"format":"uri"},"widgetUrl":{"type":["string","null"],"format":"uri"},"customDomain":{"type":["string","null"]},"customDomainUrl":{"type":["string","null"],"format":"uri"},"updatedAt":{"type":["string","null"],"format":"date-time"},"lastUpdatedAt":{"type":["string","null"],"format":"date-time"},"badges":{"type":"object","properties":{"frameworks":{"type":"array","items":{"type":"string"}},"nigeriaIndicators":{"type":"array","items":{"type":"string"}}},"required":["frameworks","nigeriaIndicators"]},"resourcesCount":{"type":"integer","minimum":0},"controlsCount":{"type":"integer","minimum":0},"showSubprocessors":{"type":"boolean"},"showDsrLink":{"type":"boolean"}},"required":["published","slug","url","widgetUrl","customDomain","customDomainUrl","updatedAt","lastUpdatedAt","badges","resourcesCount","controlsCount","showSubprocessors","showDsrLink"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `trust-center:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/exports/dossier":{"post":{"tags":["exports"],"summary":"Queue a compliance-dossier export","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["reports:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sections":{"type":"array","items":{"type":"string","enum":["overview","ropa","dpia","dsr","breach","consent","lawful-basis","xborder","policy","audit","subprocessors"]},"minItems":1},"format":{"type":"string","enum":["pdf","docx","zip"],"default":"pdf"},"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}},"required":["sections"],"additionalProperties":false}}}},"responses":{"202":{"description":"Queue a compliance-dossier export","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"exportId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["queued","running","complete","failed"]}},"required":["exportId","status"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `reports:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/exports/{id}":{"get":{"tags":["exports"],"summary":"Fetch the status of an export job","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["reports:read"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Fetch the status of an export job","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["dossier","car","ndpc_notice","report"]},"format":{"type":"string","enum":["pdf","docx","zip","json"]},"status":{"type":"string","enum":["queued","running","complete","failed"]},"fileUrl":{"type":["string","null"]},"resultMeta":{},"error":{"type":["string","null"]},"createdAt":{"type":"string"},"startedAt":{"type":["string","null"]},"completedAt":{"type":["string","null"]}},"required":["id","type","format","status","fileUrl","error","createdAt","startedAt","completedAt"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `reports:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/files/presign":{"post":{"tags":["files"],"summary":"Presign an S3 upload URL for a new file","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["files:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"filename":{"type":"string","minLength":1,"maxLength":512},"mime":{"type":"string","minLength":1,"maxLength":255},"byteSize":{"type":"integer","exclusiveMinimum":0},"module":{"type":"string","enum":["dsr","breach","dpia","policy","ropa","consent","lawful-basis","cross-border","client-onboarding"]},"purpose":{"type":"string","minLength":1,"maxLength":100},"resourceId":{"type":"string","format":"uuid"},"expectedSha256":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["filename","mime","byteSize","module","purpose"]}}}},"responses":{"201":{"description":"Presign an S3 upload URL for a new file","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `files:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/files":{"get":{"tags":["files"],"summary":"List tenant files visible to the caller","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["files:read"],"parameters":[{"schema":{"type":"string","enum":["dsr","breach","dpia","policy","ropa","consent","lawful-basis","cross-border","client-onboarding"]},"required":false,"name":"module","in":"query"},{"schema":{"type":"string"},"required":false,"name":"resourceId","in":"query"},{"schema":{"type":"string","format":"uuid"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"List tenant files visible to the caller","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"module":{"type":"string"},"resourceId":{"type":["string","null"]},"filename":{"type":"string"},"contentType":{"type":"string"},"sizeBytes":{"type":"integer","minimum":0},"scanStatus":{"type":"string","enum":["pending","clean","infected","error"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","module","resourceId","filename","contentType","sizeBytes","scanStatus","createdAt","updatedAt"]}},"nextCursor":{"type":["string","null"],"format":"uuid"}},"required":["items","nextCursor"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `files:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/files/{id}/complete":{"post":{"tags":["files"],"summary":"Mark a presigned upload as complete and enqueue the virus scan","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["files:write"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"etag":{"type":"string"}}}}}},"responses":{"200":{"description":"Mark a presigned upload as complete and enqueue the virus scan","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `files:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","x-asiri-idempotency":"required"}},"/v1/files/{id}":{"get":{"tags":["files"],"summary":"Fetch file metadata (with download URL when scan is clean)","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["files:read"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Fetch file metadata (with download URL when scan is clean)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `files:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."},"delete":{"tags":["files"],"summary":"Soft-delete a file and schedule the S3 purge","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["files:write"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"responses":{"200":{"description":"Soft-delete a file and schedule the S3 purge","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `files:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","x-asiri-idempotency":"required"}},"/v1/reports/overview":{"get":{"tags":["reports"],"summary":"Compliance overview snapshot","description":"Tenant-wide counts across all NDPA modules (DSR, breach, DPIA, consent, …).\n\nRequired API key scope: `reports:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["reports:read"],"responses":{"200":{"description":"Tenant-wide counts across all NDPA modules (DSR, breach, DPIA, consent, …).","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"generatedAt":{"type":"string"},"dsr":{"type":"object","properties":{"open":{"type":"number"},"byStatus":{"type":"object","additionalProperties":{"type":"number"}}},"required":["open","byStatus"]},"breach":{"type":"object","properties":{"open":{"type":"number"},"overdue72h":{"type":"number"},"byStatus":{"type":"object","additionalProperties":{"type":"number"}}},"required":["open","overdue72h","byStatus"]},"dpia":{"type":"object","properties":{"awaitingApproval":{"type":"number"},"blocked":{"type":"number"}},"required":["awaitingApproval","blocked"]},"consent":{"type":"object","properties":{"liveNotices":{"type":"number"}},"required":["liveNotices"]},"policy":{"type":"object","properties":{"needingReview":{"type":"number"}},"required":["needingReview"]},"ropa":{"type":"object","properties":{"reviewDue":{"type":"number"}},"required":["reviewDue"]},"lawfulBasis":{"type":"object","properties":{"legitimateInterestOutstanding":{"type":"number"}},"required":["legitimateInterestOutstanding"]},"crossBorder":{"type":"object","properties":{"expiringThisQuarter":{"type":"number"}},"required":["expiringThisQuarter"]},"prevPeriod":{"type":"object","properties":{"asOf":{"type":"string"},"dsr":{"type":"object","properties":{"open":{"type":"number"}},"required":["open"]},"breach":{"type":"object","properties":{"open":{"type":"number"},"overdue72h":{"type":"number"}},"required":["open","overdue72h"]},"dpia":{"type":"object","properties":{"awaitingApproval":{"type":"number"},"blocked":{"type":"number"}},"required":["awaitingApproval","blocked"]},"consent":{"type":"object","properties":{"liveNotices":{"type":"number"}},"required":["liveNotices"]},"policy":{"type":"object","properties":{"needingReview":{"type":"number"}},"required":["needingReview"]},"ropa":{"type":"object","properties":{"reviewDue":{"type":"number"}},"required":["reviewDue"]},"lawfulBasis":{"type":"object","properties":{"legitimateInterestOutstanding":{"type":"number"}},"required":["legitimateInterestOutstanding"]},"crossBorder":{"type":"object","properties":{"expiringThisQuarter":{"type":"number"}},"required":["expiringThisQuarter"]}},"required":["asOf","dsr","breach","dpia","consent","policy","ropa","lawfulBasis","crossBorder"]}},"required":["generatedAt","dsr","breach","dpia","consent","policy","ropa","lawfulBasis","crossBorder","prevPeriod"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/reports/frameworks":{"get":{"tags":["reports"],"summary":"Per-framework readiness","description":"For each active ControlFramework: count of requirements, count of mapped controls, and percent of those controls in `implemented` status for the tenant.\n\nRequired API key scope: `reports:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["reports:read"],"responses":{"200":{"description":"For each active ControlFramework: count of requirements, count of mapped controls, and percent of those controls in `implemented` status for the tenant.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"generatedAt":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"name":{"type":"string"},"requirements":{"type":"number"},"controls":{"type":"number"},"readyPct":{"type":"number"}},"required":["code","name","requirements","controls","readyPct"]}}},"required":["generatedAt","items"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/reports/dsr-risk-mix":{"get":{"tags":["reports"],"summary":"DSR risk-band distribution","description":"Heuristic bucketing of open DSRs by SLA pressure: overdue → high, due within 7 days → moderate, otherwise low. Closed DSRs count as none.\n\nRequired API key scope: `reports:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["reports:read"],"responses":{"200":{"description":"Heuristic bucketing of open DSRs by SLA pressure: overdue → high, due within 7 days → moderate, otherwise low. Closed DSRs count as none.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"generatedAt":{"type":"string"},"high":{"type":"number"},"moderate":{"type":"number"},"low":{"type":"number"},"none":{"type":"number"}},"required":["generatedAt","high","moderate","low","none"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/reports/forecast":{"get":{"tags":["reports"],"summary":"Monthly task forecast","description":"Counts of items due in each of the next 4 months across DSR SLA, DPIA reviews, cross-border reviews, policy reviews, and RoPA reviews.\n\nRequired API key scope: `reports:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["reports:read"],"responses":{"200":{"description":"Counts of items due in each of the next 4 months across DSR SLA, DPIA reviews, cross-border reviews, policy reviews, and RoPA reviews.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"generatedAt":{"type":"string"},"months":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"number"}},"required":["label","value"]}}},"required":["generatedAt","months"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/reports/dsr-sla":{"get":{"tags":["reports"],"summary":"DSR SLA throughput report","description":"Period-scoped DSR throughput, mean times to acknowledge and fulfil, and SLA-breach count.\n\nRequired API key scope: `reports:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["reports:read"],"parameters":[{"schema":{"type":"string","format":"date-time"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":true,"name":"to","in":"query"}],"responses":{"200":{"description":"Period-scoped DSR throughput, mean times to acknowledge and fulfil, and SLA-breach count.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"throughput":{"type":"object","properties":{"byStatus":{"type":"object","additionalProperties":{"type":"number"}},"total":{"type":"number"}},"required":["byStatus","total"]},"meanTimeToAcknowledgeSeconds":{"type":["number","null"]},"meanTimeToFulfilSeconds":{"type":["number","null"]},"slaBreachCount":{"type":"number"}},"required":["from","to","throughput","meanTimeToAcknowledgeSeconds","meanTimeToFulfilSeconds","slaBreachCount"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/reports/breach-timeline":{"get":{"tags":["reports"],"summary":"Breach incidence timeline","description":"ISO-week buckets of breach incidents over the period, grouped by severity.\n\nRequired API key scope: `reports:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["reports:read"],"parameters":[{"schema":{"type":"string","format":"date-time"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":true,"name":"to","in":"query"}],"responses":{"200":{"description":"ISO-week buckets of breach incidents over the period, grouped by severity.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"buckets":{"type":"array","items":{"type":"object","properties":{"weekStart":{"type":"string"},"total":{"type":"number"},"bySeverity":{"type":"object","additionalProperties":{"type":"number"}}},"required":["weekStart","total","bySeverity"]}}},"required":["from","to","buckets"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/reports/audit-summary":{"get":{"tags":["reports"],"summary":"Audit-event summary","description":"Counts of audit events grouped by module + action over the period.\n\nRequired API key scope: `reports:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["reports:read"],"parameters":[{"schema":{"type":"string","format":"date-time"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":true,"name":"to","in":"query"}],"responses":{"200":{"description":"Counts of audit events grouped by module + action over the period.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"rows":{"type":"array","items":{"type":"object","properties":{"module":{"type":"string"},"action":{"type":"string"},"count":{"type":"number"}},"required":["module","action","count"]}},"totalEvents":{"type":"number"}},"required":["from","to","rows","totalEvents"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}}}},"/v1/reports/build":{"post":{"tags":["reports"],"summary":"Queue a new report build","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["reports:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["audit_summary","breach_timeline","dsr_sla","posture_trend","regulator_pack"]},"format":{"type":"string","enum":["pdf","csv","json"]},"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"recipients":{"type":"array","items":{"type":"string","format":"email"},"maxItems":50}},"required":["type","format"]}}}},"responses":{"202":{"description":"Queue a new report build","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"reportId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["queued","running","succeeded","failed"]}},"required":["reportId","status"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `reports:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/reports/runs":{"get":{"tags":["reports"],"summary":"List recent report runs for this tenant","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["reports:read"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"List recent report runs for this tenant","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["audit_summary","breach_timeline","dsr_sla","posture_trend","regulator_pack"]},"format":{"type":"string","enum":["pdf","csv","json"]},"status":{"type":"string","enum":["queued","running","succeeded","failed"]},"params":{"type":"object","additionalProperties":{}},"artefactPath":{"type":["string","null"]},"artefactSize":{"type":["number","null"]},"errorMessage":{"type":["string","null"]},"scheduleId":{"type":["string","null"],"format":"uuid"},"startedAt":{"type":["string","null"]},"completedAt":{"type":["string","null"]},"createdAt":{"type":"string"}},"required":["id","type","format","status","params","artefactPath","artefactSize","errorMessage","scheduleId","startedAt","completedAt","createdAt"]}},"nextCursor":{"type":["string","null"]}},"required":["items","nextCursor"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `reports:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/reports/runs/{id}":{"get":{"tags":["reports"],"summary":"Get a single report run","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["reports:read"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Get a single report run","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["audit_summary","breach_timeline","dsr_sla","posture_trend","regulator_pack"]},"format":{"type":"string","enum":["pdf","csv","json"]},"status":{"type":"string","enum":["queued","running","succeeded","failed"]},"params":{"type":"object","additionalProperties":{}},"artefactPath":{"type":["string","null"]},"artefactSize":{"type":["number","null"]},"errorMessage":{"type":["string","null"]},"scheduleId":{"type":["string","null"],"format":"uuid"},"startedAt":{"type":["string","null"]},"completedAt":{"type":["string","null"]},"createdAt":{"type":"string"},"downloadUrl":{"type":["string","null"]}},"required":["id","type","format","status","params","artefactPath","artefactSize","errorMessage","scheduleId","startedAt","completedAt","createdAt","downloadUrl"]}},"required":["data"]}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `reports:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/webhooks/subscriptions":{"get":{"tags":["webhooks"],"summary":"List webhook subscriptions for the active tenant","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["webhooks:read"],"responses":{"200":{"description":"List webhook subscriptions for the active tenant","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `webhooks:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."},"post":{"tags":["webhooks"],"summary":"Create a webhook subscription","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["webhooks:write"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","minLength":1},"minItems":1},"pinnedVersions":{"type":"object","additionalProperties":{"type":"integer","minimum":1}},"enabled":{"type":"boolean"},"secret":{"type":"string","minLength":16}},"required":["url","events"]}}}},"responses":{"201":{"description":"Create a webhook subscription","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `webhooks:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"x-asiri-idempotency":"required"}},"/v1/webhooks/subscriptions/{id}/deliveries":{"get":{"tags":["webhooks"],"summary":"Fetch the delivery log for a subscription","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["audit:read"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Fetch the delivery log for a subscription","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `audit:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."}},"/v1/webhooks/subscriptions/{id}":{"get":{"tags":["webhooks"],"summary":"Fetch a single webhook subscription","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["webhooks:read"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Fetch a single webhook subscription","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `webhooks:read`.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps."},"patch":{"tags":["webhooks"],"summary":"Update a webhook subscription","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["webhooks:write"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","minLength":1},"minItems":1},"pinnedVersions":{"type":"object","additionalProperties":{"type":"integer","minimum":1}},"enabled":{"type":"boolean"},"rotateSecret":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Update a webhook subscription","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `webhooks:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","x-asiri-idempotency":"required"},"delete":{"tags":["webhooks"],"summary":"Delete a webhook subscription","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["webhooks:write"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"responses":{"200":{"description":"Delete a webhook subscription","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `webhooks:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","x-asiri-idempotency":"required"}},"/v1/webhooks/subscriptions/{id}/test":{"post":{"tags":["webhooks"],"summary":"Enqueue a test event for a subscription","security":[{"bearerAuth":[]}],"x-asiri-public-api":true,"x-asiri-api-scopes":["webhooks:write"],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"name":"Idempotency-Key","in":"header","required":true,"description":"Required for write requests. Use a unique key per operation and reuse it only when retrying the same request.","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{8,128}$","minLength":8,"maxLength":128},"example":"evidence-submit-20260528-001"}],"responses":{"200":{"description":"Enqueue a test event for a subscription","content":{"application/json":{"schema":{"type":"object","properties":{"data":{}}}}}},"400":{"description":"Bad request.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"401":{"description":"Unauthenticated.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"403":{"description":"Forbidden.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"409":{"description":"Conflict.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"429":{"description":"Rate limited.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}},"500":{"description":"Internal error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"issue":{"type":"string"}},"required":["path","issue"]}},"requestId":{"type":"string"}},"required":["code","message"]}},"required":["error"]}}}}},"description":"Required API key scope: `webhooks:write`.\n\nRequires an `Idempotency-Key` header on every request. Reuse the same key when retrying the same operation so ASIRI can return the same result without creating duplicate records.\n\nResponses use the standard ASIRI envelope. Keep API keys server-side; do not expose them in browser JavaScript or mobile apps.","x-asiri-idempotency":"required"}}},"webhooks":{}}