{"openapi":"3.0.0","paths":{"/v1/events":{"get":{"operationId":"V1EventsController_list","summary":"List security events (keyset-paginated, newest first)","description":"Returns OCSF-shaped events for your business. Use `next_cursor` as `?cursor=` on the next request to page; the cursor is opaque and signed.","parameters":[{"name":"type","required":false,"in":"query","description":"Filter to events of a particular type. One of `policy_violation`, `dlp_redaction`, `discovery`. Omit to receive all.","schema":{"type":"string"}},{"name":"since","required":false,"in":"query","description":"ISO-8601 lower bound (inclusive).","schema":{"format":"date-time","type":"string"}},{"name":"until","required":false,"in":"query","description":"ISO-8601 upper bound (exclusive).","schema":{"format":"date-time","type":"string"}},{"name":"cursor","required":false,"in":"query","description":"Opaque pagination cursor from a previous response's `next_cursor`. Do not construct manually — cursors are HMAC-signed.","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Page size. Max 100; default 50.","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedEventsResponseDto"}}}}},"tags":["events"],"security":[{"ApiKey":[]}]}},"/v1/events/{id}":{"get":{"operationId":"V1EventsController_getById","summary":"Get a single event by id","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1EventDto"}}}},"404":{"description":"Event not found."}},"tags":["events"],"security":[{"ApiKey":[]}]}},"/v1/guardrails/{id}/test":{"post":{"operationId":"V1GuardrailsController_test","summary":"Run a single guardrail against an ad-hoc input","description":"Evaluates the named guardrail (PII / regex / LLM / external) against the input string and returns the breaches and redactions it would generate. No event is recorded; this is a stateless probe.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestGuardrailBodyDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardrailTestResponseDto"}}}},"404":{"description":"Guardrail not found in this business."}},"tags":["guardrails"],"security":[{"ApiKey":[]}]}},"/v1/frameworks/{id}/test":{"post":{"operationId":"V1FrameworksController_test","summary":"Run a framework against an ad-hoc input","description":"Evaluates every guardrail attached to the framework against the input and returns the combined breaches/redactions. Stateless — no event recorded.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestGuardrailBodyDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FrameworkTestResponseDto"}}}},"404":{"description":"Framework not found in this business."}},"tags":["frameworks"],"security":[{"ApiKey":[]}]}},"/v1/frameworks/{id}/test-file":{"post":{"operationId":"V1FrameworksController_testFile","summary":"Run a framework against an uploaded file","description":"Multipart variant of `POST /v1/frameworks/:id/test`. For documents the file is parsed to text and run through every attached guardrail; for images the binary is sent to image guardrails. Stateless — no event recorded. For non-image documents with redactable entities the response includes an optional `redacted_file` (base64) so callers can preview/download the redacted copy; nothing is persisted.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"known_entities":{"type":"string","description":"Optional JSON-encoded known_entities map."}},"required":["file"]}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FrameworkFileTestResponseDto"}}}},"400":{"description":"Missing or unsupported file."},"404":{"description":"Framework not found in this business."}},"tags":["frameworks"],"security":[{"ApiKey":[]}]}},"/v1/users":{"get":{"operationId":"V1UsersController_list","summary":"List users in the business (keyset-paginated)","parameters":[{"name":"cursor","required":false,"in":"query","description":"Cursor from a previous response. Opaque, HMAC-signed.","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":50,"type":"number"}},{"name":"email_contains","required":false,"in":"query","description":"Substring filter on email (case-insensitive).","schema":{"type":"string"}},{"name":"status","required":false,"in":"query","schema":{"enum":["active","waiting_seat"],"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedUsersResponseDto"}}}}},"tags":["users"],"security":[{"ApiKey":[]}]}},"/v1/users/{id}":{"get":{"operationId":"V1UsersController_getById","summary":"Get a single user by id","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1UserDto"}}}},"404":{"description":"User not found in this business."}},"tags":["users"],"security":[{"ApiKey":[]}]}},"/v1/users/{id}/onboarding":{"get":{"operationId":"V1UsersController_getOnboarding","summary":"Get a user’s onboarding completion state","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingStatusDto"}}}}},"tags":["users"],"security":[{"ApiKey":[]}]},"put":{"operationId":"V1UsersController_setOnboarding","summary":"Set a user’s onboarding completion (idempotent)","description":"`{ \"completed\": true }` marks the user complete; `{ \"completed\": false }` resets the completion. Idempotent — returns the resulting state.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetOnboardingBodyDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingStatusDto"}}}}},"tags":["users"],"security":[{"ApiKey":[]}]}},"/v1/analytics/usage-summary":{"get":{"operationId":"V1AnalyticsController_usageSummary","summary":"Usage rollup over a time window, bucketed by tool / user / action / day","description":"Returns counts of prompts (total, blocked, auto-redacted, warned, flagged, no-policy, compliant) for your business between `since` and `until`, grouped by the requested dimension. Designed to feed dashboard tiles in Sentinel / Splunk / Datadog without scanning the events feed.","parameters":[{"name":"since","required":true,"in":"query","description":"ISO-8601 inclusive lower bound.","schema":{"format":"date-time","type":"string"}},{"name":"until","required":true,"in":"query","description":"ISO-8601 exclusive upper bound.","schema":{"format":"date-time","type":"string"}},{"name":"group_by","required":true,"in":"query","description":"Dimension to bucket counts by. `tool` = platform_id, `user` = user_id, `action` = the policy action enum, `day` = UTC date.","schema":{"enum":["tool","user","action","day"],"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Max buckets. 1–1000, default 100.","schema":{"minimum":1,"maximum":1000,"default":100,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageSummaryResponseDto"}}}}},"tags":["analytics"],"security":[{"ApiKey":[]}]}},"/v1/analytics/violations-summary":{"get":{"operationId":"V1AnalyticsController_violationsSummary","summary":"Policy violations over a time window, bucketed by tool / user / severity / day","description":"Restricts the population to rows where a policy actually fired (BLOCK / AUTO_REDACT / WARN / FLAG) and rolls them up. Severity assignment is platform-defined and stable: BLOCK → critical, AUTO_REDACT → high, WARN → medium, FLAG → low.","parameters":[{"name":"since","required":true,"in":"query","description":"ISO-8601 inclusive lower bound.","schema":{"format":"date-time","type":"string"}},{"name":"until","required":true,"in":"query","description":"ISO-8601 exclusive upper bound.","schema":{"format":"date-time","type":"string"}},{"name":"group_by","required":true,"in":"query","description":"Dimension to bucket violations by. `tool` = platform_id, `user` = user_id, `severity` = critical/high/medium/low (BLOCK / AUTO_REDACT / WARN / FLAG respectively), `day` = UTC date.","schema":{"enum":["tool","user","severity","day"],"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Max buckets. 1–1000, default 100.","schema":{"minimum":1,"maximum":1000,"default":100,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ViolationsSummaryResponseDto"}}}}},"tags":["analytics"],"security":[{"ApiKey":[]}]}}},"info":{"title":"Aona Public API","description":"The customer-facing /v1 surface of the Aona Workforce AI Security platform. Events are emitted in OCSF (Open Cybersecurity Schema Framework) shape.","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"ApiKey":{"type":"apiKey","in":"header","name":"X-Api-Key"}},"schemas":{"OcsfActorUserDto":{"type":"object","properties":{"uid":{"type":"string","description":"Aona user UUID, if known.","nullable":true}},"required":["uid"]},"OcsfActorDto":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/OcsfActorUserDto"}},"required":["user"]},"OcsfAppDto":{"type":"object","properties":{"name":{"type":"string","description":"Static product label.","example":"Aona"},"uid":{"type":"string","description":"AI platform UUID (e.g. ChatGPT, Claude).","nullable":true}},"required":["name","uid"]},"OcsfProductDto":{"type":"object","properties":{"name":{"type":"string","example":"Aona Workforce AI Security"}},"required":["name"]},"OcsfMetadataDto":{"type":"object","properties":{"product":{"$ref":"#/components/schemas/OcsfProductDto"},"tenant_uid":{"type":"string","description":"Aona business (tenant) UUID."}},"required":["product","tenant_uid"]},"OcsfEnrichmentDto":{"type":"object","properties":{"name":{"type":"string","description":"Enrichment name. Aona uses: `data_security_risk`, `data_privacy_risk`, `policy_id`, `action`, `chat_id`."},"value":{"type":"object","description":"Enrichment value (string/number/uuid)."},"type":{"type":"string","enum":["numeric","string","uid"]}},"required":["name","value","type"]},"V1EventDto":{"type":"object","properties":{"id":{"type":"string","description":"Stable event UUID (= analytics_prompts.id)."},"version":{"type":"string","description":"Aona webhook/event-payload version.","example":"2026-05-23"},"class_uid":{"type":"number","description":"OCSF class_uid. 6005 = Application Activity / Web Resources Activity.","example":6005},"category_name":{"type":"string","example":"Application Activity"},"activity_name":{"type":"string","example":"Access"},"time":{"type":"string","description":"Event timestamp (ISO-8601). = analytics_prompts.created_at.","format":"date-time"},"actor":{"$ref":"#/components/schemas/OcsfActorDto"},"app":{"$ref":"#/components/schemas/OcsfAppDto"},"type_name":{"type":"string","description":"Aona event class.","enum":["policy_violation","dlp_redaction","discovery"]},"disposition":{"type":"string","description":"Outcome of the policy evaluation. Aona-native values.","enum":["BLOCK","AUTO_REDACT","WARN","FLAG","NO_POLICY"]},"metadata":{"$ref":"#/components/schemas/OcsfMetadataDto"},"enrichments":{"type":"array","items":{"$ref":"#/components/schemas/OcsfEnrichmentDto"}}},"required":["id","version","class_uid","category_name","activity_name","time","actor","app","type_name","disposition","metadata","enrichments"]},"PaginatedEventsResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/V1EventDto"}},"next_cursor":{"type":"string","description":"Cursor to pass as `?cursor=` on the next request, or null if this is the last page.","nullable":true},"has_more":{"type":"boolean","description":"True if `next_cursor` is non-null."}},"required":["data","next_cursor","has_more"]},"TestGuardrailBodyDto":{"type":"object","properties":{"input":{"type":"string","description":"The prompt or text to evaluate against the guardrail. Treated as a single user message.","example":"Hi, my name is John and my SSN is 123-45-6789."},"known_entities":{"type":"object","description":"Optional pre-known entities for redaction continuity. Map of entity-type → token values.","example":{"PERSON_1":["John"],"ORGANIZATION_1":["Aona"]}}},"required":["input"]},"BreachDto":{"type":"object","properties":{"guardrail_id":{"type":"string"},"version_id":{"type":"string","description":"Active version of the guardrail that produced this breach, when resolvable. Allows callers to deep-link to the exact version that was evaluated.","nullable":true},"guardrail_name":{"type":"string"},"action":{"type":"string","enum":["BLOCK","WARN","FLAG","AUTO_REDACT","NO_POLICY","COMPLIANT"]},"message":{"type":"string","nullable":true},"priority":{"type":"number","nullable":true}},"required":["guardrail_id","guardrail_name","action","message","priority"]},"RedactionEntryDto":{"type":"object","properties":{"search":{"type":"string","description":"Original substring matched in the input."},"replace":{"type":"string","description":"Placeholder Aona would substitute."},"type":{"type":"string","description":"Entity type / label (e.g. US_SSN, PERSON).","nullable":true}},"required":["search","replace","type"]},"EntityEntryDto":{"type":"object","properties":{"value":{"type":"string","description":"The detected text as it appears in the input."},"type":{"type":"string","description":"Entity type (e.g. CREDIT_CARD_PAN, PERSON, EMAIL_ADDRESS)."},"start":{"type":"number","description":"Start character offset in the input, when available.","nullable":true},"end":{"type":"number","description":"End character offset in the input, when available.","nullable":true},"action":{"type":"string","description":"Action configured on the guardrail that detected this entity.","enum":["BLOCK","WARN","FLAG","AUTO_REDACT","REDACT","MANUAL_REDACT","AUTO_UPDATE","MANUAL_UPDATE"]},"guardrail_id":{"type":"string","description":"The guardrail id that detected this entity."},"guardrail_name":{"type":"string","description":"The guardrail name that detected this entity."}},"required":["value","type","action","guardrail_id","guardrail_name"]},"GuardrailTestResponseDto":{"type":"object","properties":{"guardrail":{"type":"object"},"compliant":{"type":"boolean","description":"True if the guardrail did not produce any breaches and no redactions were required."},"breaches":{"type":"array","items":{"$ref":"#/components/schemas/BreachDto"}},"redactions":{"type":"array","items":{"$ref":"#/components/schemas/RedactionEntryDto"}},"entities":{"description":"Every entity detected by any guardrail, with its per-entity action and originating guardrail. Superset of `redactions`: entities under FLAG/WARN/BLOCK actions appear here but NOT in `redactions`; redacted entities appear in both.","type":"array","items":{"$ref":"#/components/schemas/EntityEntryDto"}},"latency_ms":{"type":"number","description":"End-to-end evaluation time in milliseconds."}},"required":["guardrail","compliant","breaches","redactions","entities","latency_ms"]},"FrameworkTestResponseDto":{"type":"object","properties":{"framework":{"type":"object"},"compliant":{"type":"boolean"},"breaches":{"type":"array","items":{"$ref":"#/components/schemas/BreachDto"}},"redactions":{"type":"array","items":{"$ref":"#/components/schemas/RedactionEntryDto"}},"entities":{"description":"Every entity detected by any guardrail, with its per-entity action and originating guardrail. Superset of `redactions` (FLAG/WARN/BLOCK entities appear here but not in `redactions`).","type":"array","items":{"$ref":"#/components/schemas/EntityEntryDto"}},"latency_ms":{"type":"number"}},"required":["framework","compliant","breaches","redactions","entities","latency_ms"]},"RedactedFileDto":{"type":"object","properties":{"content":{"type":"string","description":"Base64-encoded content of the redacted file."},"filename":{"type":"string","description":"Suggested download filename, e.g. \"redacted_report.pdf\"."},"mimetype":{"type":"string","description":"MIME type of the redacted file."}},"required":["content","filename","mimetype"]},"FrameworkFileTestResponseDto":{"type":"object","properties":{"framework":{"type":"object"},"file":{"type":"object"},"compliant":{"type":"boolean"},"breaches":{"type":"array","items":{"$ref":"#/components/schemas/BreachDto"}},"redactions":{"type":"array","items":{"$ref":"#/components/schemas/RedactionEntryDto"}},"entities":{"description":"Every entity detected by any guardrail, with its per-entity action and originating guardrail. Superset of `redactions` (FLAG/WARN/BLOCK entities appear here but not in `redactions`).","type":"array","items":{"$ref":"#/components/schemas/EntityEntryDto"}},"parsed_preview":{"type":"string","description":"For document uploads (non-image), the first few hundred characters of the parsed text content. Useful to show admins what Aona \"saw\" inside the file.","nullable":true},"redacted_file":{"description":"For document uploads with redactable entities, a redacted copy of the file with entities replaced by placeholders, base64-encoded. Generated with the same engine as POST /policy/prompt. Null for images, files with no redactions, or unsupported types. Additive, optional field — older clients that ignore it are unaffected.","nullable":true,"allOf":[{"$ref":"#/components/schemas/RedactedFileDto"}]},"latency_ms":{"type":"number"}},"required":["framework","file","compliant","breaches","redactions","entities","latency_ms"]},"V1UserDto":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string","format":"email"},"first_name":{"type":"string","nullable":true},"last_name":{"type":"string","nullable":true},"display_name":{"type":"string","nullable":true},"avatar_url":{"type":"string","nullable":true},"role":{"type":"string","enum":["admin","manager","employee","unknown"],"description":"Role within the business that issued the API key."},"status":{"type":"string","enum":["active","waiting_seat"],"description":"Membership status in the business."},"last_activity_at":{"type":"string","description":"Last recorded activity timestamp (ISO-8601).","nullable":true,"format":"date-time"},"created_at":{"type":"string","description":"ISO-8601 timestamp when the user joined the business.","format":"date-time"}},"required":["id","email","first_name","last_name","display_name","avatar_url","role","status","last_activity_at","created_at"]},"PaginatedUsersResponseDto":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/V1UserDto"}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}},"required":["data","next_cursor","has_more"]},"OnboardingStatusDto":{"type":"object","properties":{"user_id":{"type":"string"},"onboarding_id":{"type":"string"},"completed":{"type":"boolean"}},"required":["user_id","onboarding_id","completed"]},"SetOnboardingBodyDto":{"type":"object","properties":{"completed":{"type":"boolean","description":"Desired completion state. `true` marks the user complete (idempotent); `false` resets it."}},"required":["completed"]},"UsageSummaryBucketDto":{"type":"object","properties":{"key":{"type":"string"},"total":{"type":"number"},"blocked":{"type":"number"},"auto_redacted":{"type":"number"},"warned":{"type":"number"},"flagged":{"type":"number"},"no_policy":{"type":"number"},"compliant":{"type":"number"}},"required":["key","total","blocked","auto_redacted","warned","flagged","no_policy","compliant"]},"UsageSummaryResponseDto":{"type":"object","properties":{"since":{"type":"string","format":"date-time"},"until":{"type":"string","format":"date-time"},"group_by":{"type":"string","enum":["tool","user","action","day"]},"buckets":{"type":"array","items":{"$ref":"#/components/schemas/UsageSummaryBucketDto"}}},"required":["since","until","group_by","buckets"]},"ViolationsSummaryBucketDto":{"type":"object","properties":{"key":{"type":"string"},"total":{"type":"number"},"critical":{"type":"number"},"high":{"type":"number"},"medium":{"type":"number"},"low":{"type":"number"}},"required":["key","total","critical","high","medium","low"]},"ViolationsSummaryResponseDto":{"type":"object","properties":{"since":{"type":"string","format":"date-time"},"until":{"type":"string","format":"date-time"},"group_by":{"type":"string","enum":["tool","user","severity","day"]},"buckets":{"type":"array","items":{"$ref":"#/components/schemas/ViolationsSummaryBucketDto"}}},"required":["since","until","group_by","buckets"]}}}}