openapi: 3.1.0 info: title: AiSOC Platform API description: AiSOC — open-source AI Security Operations Center. Autonomous threat detection, investigation, and response. version: 0.1.0 paths: /api/v1/auth/login: post: tags: - auth summary: Login description: Authenticate with email/password, return JWT tokens. operationId: login_api_v1_auth_login_post requestBody: content: application/json: schema: $ref: '#/components/schemas/LoginRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TokenResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/auth/refresh: post: tags: - auth summary: Refresh Token description: Refresh access token using a valid refresh token. operationId: refresh_token_api_v1_auth_refresh_post requestBody: content: application/json: schema: $ref: '#/components/schemas/RefreshRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TokenResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/auth/me: get: tags: - auth summary: Get Me description: Get current authenticated user info. operationId: get_me_api_v1_auth_me_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/UserMeResponse' security: - HTTPBearer: [] /api/v1/auth/me/preferences: patch: tags: - auth summary: Patch Me Preferences description: 'Merge user preferences (e.g. theme) into the stored JSONB column. Only the keys supplied in the request body are updated; all other existing keys are preserved. This lets the frontend evolve independent preference namespaces without overwriting each other.' operationId: patch_me_preferences_api_v1_auth_me_preferences_patch requestBody: content: application/json: schema: $ref: '#/components/schemas/PreferencesPatch' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/UserMeResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/api-keys: post: tags: - api-keys summary: Create Api Key description: 'Create a new scoped API key for the current tenant. The raw key value is returned **only once** in this response.' operationId: create_api_key_api_v1_api_keys_post parameters: - name: current_user in: query required: true schema: title: Current User requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateApiKeyRequest' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CreateApiKeyResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' get: tags: - api-keys summary: List Api Keys description: List all API keys for the current tenant (raw keys are never returned). operationId: list_api_keys_api_v1_api_keys_get security: - HTTPBearer: [] responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/ApiKeyOut' title: Response List Api Keys Api V1 Api Keys Get /api/v1/api-keys/{key_id}: get: tags: - api-keys summary: Get Api Key description: Get metadata for a specific API key. operationId: get_api_key_api_v1_api_keys__key_id__get security: - HTTPBearer: [] parameters: - name: key_id in: path required: true schema: type: string format: uuid title: Key Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ApiKeyOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' patch: tags: - api-keys summary: Update Api Key description: Update an API key's name, scopes, or expiry. operationId: update_api_key_api_v1_api_keys__key_id__patch parameters: - name: key_id in: path required: true schema: type: string format: uuid title: Key Id - name: current_user in: query required: true schema: title: Current User requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateApiKeyRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ApiKeyOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - api-keys summary: Revoke Api Key description: Revoke (deactivate) an API key. The key can no longer be used for authentication. operationId: revoke_api_key_api_v1_api_keys__key_id__delete parameters: - name: key_id in: path required: true schema: type: string format: uuid title: Key Id - name: current_user in: query required: true schema: title: Current User responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/submit: post: tags: - alerts summary: Submit Alert description: "Submit one alert directly from an OCSF event batch.\n\nThis is\ \ the destination for `aisoc submit ` and the local-dev fast\npath documented\ \ in the quickstart. We deliberately bypass the Kafka\ndetect/correlate/fuse\ \ pipeline (which fresh clones don't run by default)\nso that a hand-crafted\ \ fixture lands in the database — and therefore in\n``GET /api/v1/alerts``\ \ and the web console — within the same second.\n\n**Hardening (Batch 8 /\ \ H-5)**:\n\n* **Payload caps** — events are first run through\n :func:`app.services.event_sanitiser.sanitise_event_batch`,\ \ which\n enforces ``AISOC_SUBMIT_MAX_EVENTS`` (default 200), per-event size\n\ \ ``AISOC_SUBMIT_MAX_EVENT_BYTES`` (default 64 KiB), and total batch\n size\ \ ``AISOC_SUBMIT_MAX_TOTAL_BYTES`` (default 1 MiB). Violations\n return ``413\ \ Payload Too Large`` rather than the 200 OK + truncated\n alert we used\ \ to silently emit.\n* **Secret redaction** — the sanitiser also redacts keys\ \ matching\n common secret patterns (``password``, ``token``, ``api_key``,\ \ …)\n *before* the payload is persisted to ``alerts.raw_event``, so a\n\ \ leaky connector cannot smuggle bearer tokens into the alert table\n where\ \ they would be visible to every analyst with ``alerts:read``.\n* **Idempotency**\ \ — when the client supplies an ``Idempotency-Key``\n header, the resulting\ \ alert is keyed ``(tenant_id, idempotency_key)``\n via a partial unique\ \ index (migration ``044``). A retry of the\n same key resolves to the existing\ \ row and returns HTTP ``200``\n instead of creating a duplicate, so at-least-once\ \ connectors and\n the ``aisoc submit`` CLI can retry safely on network blips.\n\ * **Timestamp bounds** — event timestamps outside the configured\n retention\ \ window are clamped (see\n :mod:`app.services.timestamp_bounds`); the resulting\ \ alert is\n tagged ``ts-clamped`` so analysts can see the connector misbehaved.\n\ \nAuthorisation: requires ``alerts:write``. In development mode the\nauth\ \ bypass in :mod:`app.api.v1.deps` resolves to the deterministic\ndemo tenant,\ \ so the documented ``aisoc submit`` CLI works against a\nfresh clone with\ \ no token plumbing." operationId: submit_alert_api_v1_alerts_submit_post security: - HTTPBearer: [] parameters: - name: Idempotency-Key in: header required: false schema: anyOf: - type: string - type: 'null' description: Optional opaque client-supplied key (8–128 chars, [A-Za-z0-9._:-]). When supplied, a retry of the same key for the same tenant returns the existing alert with HTTP 200 instead of creating a duplicate. title: Idempotency-Key description: Optional opaque client-supplied key (8–128 chars, [A-Za-z0-9._:-]). When supplied, a retry of the same key for the same tenant returns the existing alert with HTTP 200 instead of creating a duplicate. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AlertSubmitRequest' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AlertResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts: get: tags: - alerts summary: List Alerts description: 'List alerts for the current tenant with filtering and pagination. `min_confidence` / `confidence_label` let the queue workbench (PR-5) and /alerts page filter on the fusion-emitted confidence signal (W3). Alerts that pre-date the confidence column will have NULL and therefore won''t match either filter — that''s intentional; analysts who care about confidence should only see alerts that actually carry the signal.' operationId: list_alerts_api_v1_alerts_get security: - HTTPBearer: [] parameters: - name: page in: query required: false schema: type: integer minimum: 1 default: 1 title: Page - name: page_size in: query required: false schema: type: integer maximum: 200 minimum: 1 default: 25 title: Page Size - name: severity in: query required: false schema: anyOf: - type: string - type: 'null' title: Severity - name: status in: query required: false schema: anyOf: - type: string - type: 'null' title: Status - name: category in: query required: false schema: anyOf: - type: string - type: 'null' title: Category - name: assigned_to_me in: query required: false schema: type: boolean default: false title: Assigned To Me - name: search in: query required: false schema: anyOf: - type: string - type: 'null' title: Search - name: min_confidence in: query required: false schema: anyOf: - type: integer maximum: 100 minimum: 0 - type: 'null' title: Min Confidence - name: confidence_label in: query required: false schema: anyOf: - type: string - type: 'null' title: Confidence Label responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AlertListResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/stats: get: tags: - alerts summary: Get Alert Stats description: Get alert statistics for the dashboard. operationId: get_alert_stats_api_v1_alerts_stats_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AlertStatsResponse' security: - HTTPBearer: [] /api/v1/alerts/queue: get: tags: - alerts summary: Get Alert Queue description: 'Investigation Queue workbench feed. Returns the prioritised list of alerts the analyst should work on next: alerts assigned to them, followed by unassigned critical/high alerts, ordered by SLA due time. The endpoint also returns ``counts`` for both buckets unconditionally so the topbar badge and the workbench tabs can render without an extra round-trip.' operationId: get_alert_queue_api_v1_alerts_queue_get security: - HTTPBearer: [] parameters: - name: owner in: query required: false schema: enum: - me - unassigned - all type: string default: all title: Owner - name: period in: query required: false schema: enum: - 24h - 7d - 30d - all type: string default: all title: Period - name: page in: query required: false schema: type: integer minimum: 1 default: 1 title: Page - name: page_size in: query required: false schema: type: integer maximum: 200 minimum: 1 default: 50 title: Page Size responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/QueueResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/{alert_id}: get: tags: - alerts summary: Get Alert description: "Get a single alert by ID, enriched with Investigation Rail data.\n\ \nThe endpoint returns the standard alert fields plus everything the\nrail\ \ needs to render in one shot:\n\n* a deterministic ``narrative`` (lazily\ \ filled and persisted if the\n row was created before fusion started emitting\ \ it),\n* ``related_entities`` grouped for pivot,\n* a compact ``mini_timeline``,\n\ * normalised ``recommended_actions``.\n\nThe lazy-fill is best-effort: if\ \ the narrative builder ever raises\nwe log and return the alert with ``narrative=None``\ \ so the page\nkeeps rendering. The frontend already handles the null case." operationId: get_alert_api_v1_alerts__alert_id__get security: - HTTPBearer: [] parameters: - name: alert_id in: path required: true schema: type: string format: uuid title: Alert Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AlertDetailResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' patch: tags: - alerts summary: Update Alert description: Update alert status, priority, tags, assignment, or case link. operationId: update_alert_api_v1_alerts__alert_id__patch security: - HTTPBearer: [] parameters: - name: alert_id in: path required: true schema: type: string format: uuid title: Alert Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AlertUpdateRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AlertResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/{alert_id}/escalate: post: tags: - alerts summary: Escalate Alert description: Escalate an alert (raises severity by one level). operationId: escalate_alert_api_v1_alerts__alert_id__escalate_post security: - HTTPBearer: [] parameters: - name: alert_id in: path required: true schema: type: string format: uuid title: Alert Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AlertResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/{alert_id}/claim: post: tags: - alerts summary: Claim Alert Endpoint description: 'Atomically claim an unassigned alert for the current user. Returns ``409 Conflict`` if the alert is already assigned to someone else — the claim is a compare-and-set on ``assigned_to_id``, so two analysts racing for the same alert never both win.' operationId: claim_alert_endpoint_api_v1_alerts__alert_id__claim_post security: - HTTPBearer: [] parameters: - name: alert_id in: path required: true schema: type: string format: uuid title: Alert Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AlertResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/{alert_id}/snooze: post: tags: - alerts summary: Snooze Alert description: 'Defer an alert for a fixed window from the mobile responder PWA. Either ``duration_minutes`` or ``until`` must be supplied. The alert re-surfaces in the queue once ``snoozed_until`` is in the past.' operationId: snooze_alert_api_v1_alerts__alert_id__snooze_post security: - HTTPBearer: [] parameters: - name: alert_id in: path required: true schema: type: string format: uuid title: Alert Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AlertSnoozeRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AlertResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/alerts/{alert_id}/explain: post: tags: - alerts summary: Generate a structured AI explanation for an alert description: 'Return a structured explanation for one alert. This is the *single-shot* counterpart to the agent service''s NDJSON stream. Use this when the client is a non-interactive consumer (PDF builder, SOAR playbook, mobile app) or when the UI just wants the final payload without rendering tokens.' operationId: explain_alert_api_v1_alerts__alert_id__explain_post security: - HTTPBearer: [] parameters: - name: alert_id in: path required: true schema: type: string format: uuid title: Alert Id responses: '200': description: Structured explanation payload (rule lineage, MITRE, FPR, actions, summary) content: application/json: schema: type: object additionalProperties: true title: Response Explain Alert Api V1 Alerts Alert Id Explain Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases: get: tags: - cases summary: List cases operationId: list_cases_api_v1_cases_get security: - HTTPBearer: [] parameters: - name: status in: query required: false schema: anyOf: - type: string - type: 'null' title: Status - name: severity in: query required: false schema: anyOf: - type: string - type: 'null' title: Severity - name: assignee in: query required: false schema: anyOf: - type: string - type: 'null' title: Assignee - name: limit in: query required: false schema: type: integer maximum: 500 minimum: 1 default: 50 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/CaseResponse' title: Response List Cases Api V1 Cases Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - cases summary: Create case operationId: create_case_api_v1_cases_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateCaseRequest' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CaseResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}: get: tags: - cases summary: Get case operationId: get_case_api_v1_cases__case_id__get security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CaseResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' patch: tags: - cases summary: Update case operationId: update_case_api_v1_cases__case_id__patch security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateCaseRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CaseResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/alerts: post: tags: - cases summary: Link alerts to a case operationId: add_alerts_api_v1_cases__case_id__alerts_post security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AddAlertsRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CaseResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/observables: post: tags: - cases summary: Update observable graph operationId: update_observables_api_v1_cases__case_id__observables_post security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateObservablesRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CaseResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/comments: post: tags: - cases summary: Add comment operationId: add_comment_api_v1_cases__case_id__comments_post security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AddCommentRequest' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CommentResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' get: tags: - cases summary: List case comments operationId: list_comments_api_v1_cases__case_id__comments_get security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/CommentResponse' title: Response List Comments Api V1 Cases Case Id Comments Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/notes: get: tags: - cases summary: List case notes (alias of /comments) operationId: list_notes_api_v1_cases__case_id__notes_get security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/CommentResponse' title: Response List Notes Api V1 Cases Case Id Notes Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - cases summary: Add case note (alias of /comments) operationId: add_note_api_v1_cases__case_id__notes_post security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AddCommentRequest' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CommentResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/evidence: get: tags: - cases summary: Export evidence chain report operationId: evidence_report_api_v1_cases__case_id__evidence_get security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/EvidenceReport' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/timeline: get: tags: - cases summary: Case activity timeline operationId: case_timeline_api_v1_cases__case_id__timeline_get security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/app__api__v1__endpoints__cases__TimelineResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/tasks: get: tags: - cases summary: List case tasks operationId: list_tasks_api_v1_cases__case_id__tasks_get security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/TaskResponse' title: Response List Tasks Api V1 Cases Case Id Tasks Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - cases summary: Create task operationId: create_task_api_v1_cases__case_id__tasks_post security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateTaskRequest' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TaskResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/tasks/{task_id}: patch: tags: - cases summary: Update task operationId: update_task_api_v1_cases__case_id__tasks__task_id__patch security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id - name: task_id in: path required: true schema: type: string format: uuid title: Task Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateTaskRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TaskResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/investigate: post: tags: - cases summary: Launch investigation for case operationId: case_investigate_api_v1_cases__case_id__investigate_post security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/InvestigateRequest' responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response Case Investigate Api V1 Cases Case Id Investigate Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/investigations: get: tags: - cases summary: List investigation runs for a case description: 'List all investigation runs for a case. The agents service is the source of truth. When it''s unreachable we return an empty list rather than 503 so the case detail page still renders.' operationId: list_case_investigations_api_v1_cases__case_id__investigations_get security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response List Case Investigations Api V1 Cases Case Id Investigations Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/investigations/{run_id}: get: tags: - cases summary: Get investigation run operationId: case_investigation_run_api_v1_cases__case_id__investigations__run_id__get security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id - name: run_id in: path required: true schema: type: string title: Run Id responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response Case Investigation Run Api V1 Cases Case Id Investigations Run Id Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/summary: get: tags: - cases summary: Download the per-case auto-summary (JSON or HTML) operationId: case_auto_summary_api_v1_cases__case_id__summary_get security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id - name: format in: query required: false schema: enum: - json - html type: string description: Response format. ``json`` returns the structured CaseAutoSummary; ``html`` returns a print-ready report (use the browser's Save-as-PDF affordance for archival). default: json title: Format description: Response format. ``json`` returns the structured CaseAutoSummary; ``html`` returns a print-ready report (use the browser's Save-as-PDF affordance for archival). responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/postmortem: get: tags: - cases summary: Download the per-case blameless post-mortem (JSON or HTML) description: 'Generate a deterministic blameless post-mortem for one case. Distinct from ``/summary``: the summary is a snapshot of *what the case looks like right now*; the post-mortem is a retrospective oriented around *what happened, when did we find out, what did we do, and what should we change*. Both are deterministic — same case state in, same artefact out.' operationId: case_auto_postmortem_api_v1_cases__case_id__postmortem_get security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id - name: format in: query required: false schema: enum: - json - html type: string description: Response format. ``json`` returns the structured CasePostmortem; ``html`` returns a print-ready blameless retrospective (use the browser's Save-as-PDF affordance for the runbook archive). default: json title: Format description: Response format. ``json`` returns the structured CasePostmortem; ``html`` returns a print-ready blameless retrospective (use the browser's Save-as-PDF affordance for the runbook archive). responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/investigations/{run_id}/report.pdf: get: tags: - cases summary: Download investigation PDF report operationId: case_investigation_pdf_api_v1_cases__case_id__investigations__run_id__report_pdf_get security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id - name: run_id in: path required: true schema: type: string title: Run Id responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/related: get: tags: - cases summary: List related cases (by alert/observable overlap) description: 'Return other cases that share alerts or observables with this case. This is intentionally a lightweight heuristic — we look for cases that overlap on `alert_ids` or share an observable IP/host. It''s the smallest thing the case detail page needs to stop 404''ing.' operationId: list_related_cases_api_v1_cases__case_id__related_get security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response List Related Cases Api V1 Cases Case Id Related Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/cases/{case_id}/attack-chain: get: tags: - cases summary: Get Attack Chain description: 'Return the ranked attack-chain timeline for the case''s seed alert. The seed alert is the earliest ``alert.event_time`` linked to the case. If the case has no linked alerts the response is an empty chain — never a 500.' operationId: get_attack_chain_api_v1_cases__case_id__attack_chain_get security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string format: uuid title: Case Id - name: window in: query required: false schema: enum: - 1h - 6h - 24h - 72h - 7d - 30d type: string default: 24h title: Window responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response Get Attack Chain Api V1 Cases Case Id Attack Chain Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/connectors/catalog: get: tags: - connectors summary: List Catalog description: 'Return the catalog of available connectors with their schemas. The wizard calls this once on open to populate the connector picker and to render the schema-driven configuration form. It is tenant-agnostic — every tenant in this build sees the same catalog — but still gated behind authentication.' operationId: list_catalog_api_v1_connectors_catalog_get responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response List Catalog Api V1 Connectors Catalog Get security: - HTTPBearer: [] /api/v1/connectors/health: get: tags: - connectors summary: Connector Health Summary description: 'Aggregate per-tenant connector health for the dashboard tile. Single SELECT scan; we deliberately do *not* group in SQL because Postgres'' filter expressions over a few hundred rows are negligible compared to the round-trip, and the resulting Python is a lot easier to read than five COUNT(*) FILTER clauses.' operationId: connector_health_summary_api_v1_connectors_health_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ConnectorHealthSummary' security: - HTTPBearer: [] /api/v1/connectors/test: post: tags: - connectors summary: Test Connection description: 'Wizard-side "Test connection" before saving. The wizard sends plaintext credentials directly here. We validate the connector type against the catalog, then forward the payload to the connectors microservice''s stateless test endpoint. **Nothing is persisted** — these credentials never touch Postgres or the vault.' operationId: test_connection_api_v1_connectors_test_post requestBody: content: application/json: schema: $ref: '#/components/schemas/TestConnectionRequest' required: true responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Test Connection Api V1 Connectors Test Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/connectors: get: tags: - connectors summary: List Connectors description: List all connector instances for the caller's tenant. operationId: list_connectors_api_v1_connectors_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/ConnectorResponse' type: array title: Response List Connectors Api V1 Connectors Get security: - HTTPBearer: [] post: tags: - connectors summary: Create Connector description: 'Create a new connector instance. ``connector_type`` is validated against the live catalog. ``category`` defaults to the catalog entry''s category if the caller doesn''t override it — that''s the common case and keeps the wizard payload small. ``auth_config`` is encrypted with the credential vault before it touches Postgres.' operationId: create_connector_api_v1_connectors_post requestBody: content: application/json: schema: $ref: '#/components/schemas/CreateConnectorRequest' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ConnectorResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/connectors/{connector_id}: get: tags: - connectors summary: Get Connector description: Get a connector instance by ID, scoped to the caller's tenant. operationId: get_connector_api_v1_connectors__connector_id__get security: - HTTPBearer: [] parameters: - name: connector_id in: path required: true schema: type: string format: uuid title: Connector Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ConnectorResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' patch: tags: - connectors summary: Update Connector description: 'Update a connector''s configuration or state. The PATCH semantics here are deliberately conservative: only fields the caller actually supplies are touched. Notably, sending an empty ``auth_config`` dict will overwrite all secrets — the wizard must therefore omit the field entirely when the operator hasn''t re-typed credentials.' operationId: update_connector_api_v1_connectors__connector_id__patch security: - HTTPBearer: [] parameters: - name: connector_id in: path required: true schema: type: string format: uuid title: Connector Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateConnectorRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ConnectorResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - connectors summary: Delete Connector description: Delete a connector instance. operationId: delete_connector_api_v1_connectors__connector_id__delete security: - HTTPBearer: [] parameters: - name: connector_id in: path required: true schema: type: string format: uuid title: Connector Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/connectors/{connector_id}/capabilities: put: tags: - connectors summary: Update Connector Capabilities description: "Downscope which capabilities the agent may invoke against this\ \ instance.\n\nThe contract:\n\n* ``allowed_capabilities = None`` clears the\ \ downscope. The agent reverts\n to the connector class's full ``capabilities()``\ \ declaration.\n* ``allowed_capabilities = []`` is a *legitimate* operator\ \ action: it\n pins the agent to zero capabilities for this instance. Polling\ \ and\n data ingestion are unaffected — only agent-initiated actions are\n\ \ gated by this column.\n* Any string in the list MUST appear in the connector\ \ class's declared\n capabilities. We validate against the live catalog so\ \ a tampered\n request can't widen the agent's reach beyond what the connector\ \ code\n actually implements.\n\nThe narrowing happens at the read path\n\ (``BaseConnector.effective_capabilities()``), not here, so the column\nis\ \ purely a per-instance allow-list — flipping it back to ``None``\ninstantly\ \ restores the class default with no migration." operationId: update_connector_capabilities_api_v1_connectors__connector_id__capabilities_put security: - HTTPBearer: [] parameters: - name: connector_id in: path required: true schema: type: string format: uuid title: Connector Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateCapabilitiesRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ConnectorResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/connectors/{connector_id}/test: post: tags: - connectors summary: Test Existing Connector description: "Run a live ``test_connection`` against a saved connector instance.\n\ \nFlow:\n\n1. Fetch the row, scoped to the caller's tenant.\n2. Decrypt ``auth_config``\ \ via the vault.\n3. Forward to the connectors microservice with both the\ \ decrypted\n credentials and the non-secret ``connector_config``.\n4. Update\ \ the row's ``health_status`` / ``last_health_check`` based on\n the verdict\ \ so the dashboard reflects reality." operationId: test_existing_connector_api_v1_connectors__connector_id__test_post security: - HTTPBearer: [] parameters: - name: connector_id in: path required: true schema: type: string format: uuid title: Connector Id responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response Test Existing Connector Api V1 Connectors Connector Id Test Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/connectors/{connector_id}/last_event_at: get: tags: - connectors summary: Get Last Event At description: 'Return event-arrival watermark for the onboarding verify screen. Polled by the wizard''s "verify data flowing" panel every few seconds after a connector is saved. Returns 200 with ``data_flowing=false`` rather than a 404 so the polling loop has stable shape until the first event lands. The ``data_flowing`` boolean is computed server side from a fixed window (see ``_DATA_FLOWING_WINDOW_SECONDS``) so every client agrees on the rule.' operationId: get_last_event_at_api_v1_connectors__connector_id__last_event_at_get security: - HTTPBearer: [] parameters: - name: connector_id in: path required: true schema: type: string format: uuid title: Connector Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/LastEventResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/connectors/troubleshoot: post: tags: - connectors summary: Troubleshoot Connection description: 'Return structured fix suggestions for a failed connector test. The wizard calls this when ``test_connection`` returns ``success=false``. Auth-config keys (not values) are forwarded so future LLM-backed versions can hint about which field to revisit, while keeping the request safe to log.' operationId: troubleshoot_connection_api_v1_connectors_troubleshoot_post requestBody: content: application/json: schema: $ref: '#/components/schemas/TroubleshootRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TroubleshootResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/connectors/{connector_id}/push/refresh: post: tags: - connectors summary: Refresh Ingest Token description: 'Generate (or rotate) the per-connector push-ingest token. Operators click "Reveal push URL" in the wizard, which calls this and renders the resulting curl example. Re-calling rotates the token and invalidates the old one — the typical use case is "I think this URL leaked into a Slack message, give me a new one".' operationId: refresh_ingest_token_api_v1_connectors__connector_id__push_refresh_post security: - HTTPBearer: [] parameters: - name: connector_id in: path required: true schema: type: string format: uuid title: Connector Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/IngestTokenResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/oauth/app/{connector_type}: get: tags: - oauth summary: Get Oauth App description: Return the tenant's registered OAuth app (without the secret). operationId: get_oauth_app_api_v1_oauth_app__connector_type__get security: - HTTPBearer: [] parameters: - name: connector_type in: path required: true schema: type: string title: Connector Type responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/OAuthAppView' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' put: tags: - oauth summary: Upsert Oauth App description: Register or rotate the tenant's OAuth client for this connector class. operationId: upsert_oauth_app_api_v1_oauth_app__connector_type__put security: - HTTPBearer: [] parameters: - name: connector_type in: path required: true schema: type: string title: Connector Type requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/OAuthAppRegistration' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/OAuthAppView' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - oauth summary: Delete Oauth App description: Unregister the tenant's OAuth app for this connector class. operationId: delete_oauth_app_api_v1_oauth_app__connector_type__delete security: - HTTPBearer: [] parameters: - name: connector_type in: path required: true schema: type: string title: Connector Type responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/oauth/start: get: tags: - oauth summary: Oauth Start description: Mint a state nonce and bounce the operator to the provider's authorize URL. operationId: oauth_start_api_v1_oauth_start_get security: - HTTPBearer: [] parameters: - name: connector_type in: query required: true schema: type: string description: Connector class to OAuth into title: Connector Type description: Connector class to OAuth into - name: connector_id in: query required: false schema: anyOf: - type: string format: uuid - type: 'null' description: Re-auth target; omit to mint a new connector title: Connector Id description: Re-auth target; omit to mint a new connector - name: return_to in: query required: false schema: anyOf: - type: string - type: 'null' description: Where to land after callback (defaults to /onboarding) title: Return To description: Where to land after callback (defaults to /onboarding) - name: name in: query required: false schema: anyOf: - type: string - type: 'null' description: Operator-supplied display name for new connectors title: Name description: Operator-supplied display name for new connectors - name: extras in: query required: false schema: anyOf: - type: string - type: 'null' description: JSON dict of provider-specific extras (e.g. organization for GitHub) title: Extras description: JSON dict of provider-specific extras (e.g. organization for GitHub) - name: response_mode in: query required: false schema: type: string pattern: ^(redirect|json)$ default: redirect title: Response Mode responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/oauth/callback: get: tags: - oauth summary: Oauth Callback description: 'Handle the provider''s redirect after the operator consents. No auth dependency: this endpoint is invoked by the *browser* after a third-party redirect, not by an authenticated console session. The CSRF defence is the ``state`` nonce, which we issued ourselves at /oauth/start under an authenticated session.' operationId: oauth_callback_api_v1_oauth_callback_get parameters: - name: code in: query required: false schema: anyOf: - type: string - type: 'null' title: Code - name: state in: query required: false schema: anyOf: - type: string - type: 'null' title: State - name: error in: query required: false schema: anyOf: - type: string - type: 'null' title: Error - name: error_description in: query required: false schema: anyOf: - type: string - type: 'null' title: Error Description responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/tenants/me/identity: get: tags: - tenants summary: Get My Tenant Identity description: 'Get minimal tenant identity for the current user. Returns only `id`, `name`, `mssp_role`, and `parent_tenant_id`. This is safe for **any** authenticated user (analyst, viewer, responder, etc.) because it does not expose plan, settings, or limits. Used by the SOC console TopBar to render the tenant switcher pill and role badge.' operationId: get_my_tenant_identity_api_v1_tenants_me_identity_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TenantHeaderResponse' security: - HTTPBearer: [] /api/v1/tenants/me: get: tags: - tenants summary: Get My Tenant description: Get the current user's tenant details (full config — requires settings:read). operationId: get_my_tenant_api_v1_tenants_me_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TenantResponse' security: - HTTPBearer: [] /api/v1/tenants/me/settings: patch: tags: - tenants summary: Update Tenant Settings description: Update tenant settings. operationId: update_tenant_settings_api_v1_tenants_me_settings_patch requestBody: content: application/json: schema: $ref: '#/components/schemas/UpdateTenantSettingsRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TenantResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/tenants/me/users: get: tags: - tenants summary: List Users description: List all users in the current tenant. operationId: list_users_api_v1_tenants_me_users_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/UserResponse' type: array title: Response List Users Api V1 Tenants Me Users Get security: - HTTPBearer: [] post: tags: - tenants summary: Create User description: Create a new user in the current tenant. operationId: create_user_api_v1_tenants_me_users_post requestBody: content: application/json: schema: $ref: '#/components/schemas/CreateUserRequest' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/UserResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/tenants/me/users/{user_id}: patch: tags: - tenants summary: Update User description: Update a user. operationId: update_user_api_v1_tenants_me_users__user_id__patch security: - HTTPBearer: [] parameters: - name: user_id in: path required: true schema: type: string format: uuid title: User Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateUserRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/UserResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/rules: get: tags: - detection_rules summary: List Rules description: 'List detection rules for the tenant. Returns the tenant''s own rules, plus optionally platform-wide built-in rules and rules sourced from MSSP-assigned rule packs (with excluded overrides removed).' operationId: list_rules_api_v1_rules_get security: - HTTPBearer: [] parameters: - name: category in: query required: false schema: anyOf: - type: string - type: 'null' title: Category - name: rule_language in: query required: false schema: anyOf: - type: string - type: 'null' title: Rule Language - name: include_builtin in: query required: false schema: type: boolean default: true title: Include Builtin - name: include_packs in: query required: false schema: type: boolean default: true title: Include Packs responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/DetectionRuleResponse' title: Response List Rules Api V1 Rules Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - detection_rules summary: Create Rule description: Create a new detection rule. operationId: create_rule_api_v1_rules_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateRuleRequest' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/DetectionRuleResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/rules/{rule_id}: get: tags: - detection_rules summary: Get Rule description: Get a detection rule by ID. operationId: get_rule_api_v1_rules__rule_id__get security: - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: string format: uuid title: Rule Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/DetectionRuleResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' patch: tags: - detection_rules summary: Update Rule description: Update a detection rule (only tenant-owned rules). operationId: update_rule_api_v1_rules__rule_id__patch security: - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: string format: uuid title: Rule Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/app__api__v1__endpoints__detection_rules__UpdateRuleRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/DetectionRuleResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - detection_rules summary: Delete Rule description: Delete a tenant-owned detection rule. operationId: delete_rule_api_v1_rules__rule_id__delete security: - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: string format: uuid title: Rule Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/rules/{rule_id}/execute: post: tags: - detection_rules summary: Execute a detection rule against provided events description: 'Execute a single detection rule against a set of events and return matches. Useful for testing rules in the detection IDE before enabling them.' operationId: execute_detection_rule_api_v1_rules__rule_id__execute_post security: - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: string format: uuid title: Rule Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ExecuteRuleRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ExecuteRuleResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/rules/hunt: post: tags: - detection_rules summary: 'Threat hunt: run detection rules against a set of events' description: "Run multiple detection rules against provided events (threat hunting).\n\ \nThe effective rule set is resolved through\n:func:`app.services.mssp_rule_resolver.resolve_effective_rules`,\ \ which layers:\n\n 1. Tenant-owned rules\n 2. Platform-wide built-in rules\n\ \ 3. Rules sourced from MSSP-assigned rule packs\n 4. Per-tenant exclude\ \ / customize overrides\n\nIf ``rule_ids`` is omitted, all active rules in\ \ the resolved set are used." operationId: hunt_api_v1_rules_hunt_post requestBody: content: application/json: schema: $ref: '#/components/schemas/HuntRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/app__api__v1__endpoints__detection_rules__HuntResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/detection/rules: get: tags: - detection_rules summary: List Rules Compat description: List detection rules visible to the current tenant (built-ins + tenant-owned). operationId: list_rules_compat_api_v1_detection_rules_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ListResponse' security: - HTTPBearer: [] post: tags: - detection_rules summary: Create Rule Compat description: Create a tenant-owned detection rule using the frontend shape. operationId: create_rule_compat_api_v1_detection_rules_post requestBody: content: application/json: schema: $ref: '#/components/schemas/CreateBody' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FrontendDetectionRule' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/detection/rules/{rule_id}: get: tags: - detection_rules summary: Get Rule Compat description: Fetch a single rule by ID in the frontend shape. operationId: get_rule_compat_api_v1_detection_rules__rule_id__get security: - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: string format: uuid title: Rule Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FrontendDetectionRule' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' patch: tags: - detection_rules summary: Update Rule Compat description: Update a tenant-owned rule using the frontend shape. operationId: update_rule_compat_api_v1_detection_rules__rule_id__patch security: - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: string format: uuid title: Rule Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateBody' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FrontendDetectionRule' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - detection_rules summary: Delete Rule Compat description: Delete a tenant-owned rule. operationId: delete_rule_compat_api_v1_detection_rules__rule_id__delete security: - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: string format: uuid title: Rule Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/detection/test: post: tags: - detection_rules summary: Test Rule Compat description: 'Run an ad-hoc rule body against an optional sample event blob. The detection IDE in the analyst console hits this with the rule body the user is actively editing, which has not been persisted yet, so the rule never needs to live in the database.' operationId: test_rule_compat_api_v1_detection_test_post requestBody: content: application/json: schema: $ref: '#/components/schemas/TestBody' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TestResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/detection/coverage: get: tags: - detection_rules summary: Get Detection Coverage description: 'Rule-centric MITRE ATT&CK coverage for the current tenant. Distinct from ``/api/v1/graph/mitre/coverage`` which derives coverage from *alerts* — this one is what an analyst opens before a tuning sprint to answer "which techniques is my rule library blind to?".' operationId: get_detection_coverage_api_v1_detection_coverage_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CoverageResponse' security: - HTTPBearer: [] /api/v1/detection/rules/bulk-toggle: post: tags: - detection_rules summary: Bulk Toggle Rules description: 'Enable or disable many tenant-owned rules in one round-trip. Built-in / cross-tenant rules are silently skipped (returned in ``skipped``) so an MSSP analyst toggling a whole category from the UI doesn''t get a 403 just because one of the rules is platform-provided.' operationId: bulk_toggle_rules_api_v1_detection_rules_bulk_toggle_post requestBody: content: application/json: schema: $ref: '#/components/schemas/BulkToggleBody' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/BulkToggleResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/detection/drift: get: tags: - detection_rules summary: Get Detection Drift description: 'Detection drift inbox — rules that need an analyst''s attention. Surfaces rules with elevated FP rate, low confidence, or stale (no recent triggers despite being enabled). The UI renders this as a tab on the Detections page so analysts have a single queue to work instead of paginating the full library hunting for noise.' operationId: get_detection_drift_api_v1_detection_drift_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/DriftResponse' security: - HTTPBearer: [] /api/v1/detection/confidence: get: tags: - detection_rules summary: Get Detection Confidence description: 'Rule-confidence trend panel for the WS-B3 Detections UI. Returns a 4-bucket histogram of rule confidence, the per-tactic average, and the top/bottom rules so analysts can see at a glance where the rule library is brittle and which tactics need the most tuning love. No history table is needed — this view derives its trend signal from the current confidence/FP-rate columns set by the rule engine and operator review on every match.' operationId: get_detection_confidence_api_v1_detection_confidence_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ConfidenceResponse' security: - HTTPBearer: [] /api/v1/detection-proposals: get: tags: - detection_rules - dac summary: List Proposals description: List detection rule proposals visible to the caller. operationId: list_proposals_api_v1_detection_proposals_get security: - HTTPBearer: [] parameters: - name: status in: query required: false schema: anyOf: - type: string - type: 'null' title: Status - name: limit in: query required: false schema: type: integer maximum: 500 minimum: 1 default: 100 title: Limit responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/ProposalResponse' title: Response List Proposals Api V1 Detection Proposals Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - detection_rules - dac summary: Create Proposal description: Open a new detection proposal in `proposed` state. operationId: create_proposal_api_v1_detection_proposals_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateProposalRequest' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ProposalResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/detection-proposals/baselines: get: tags: - detection_rules - dac summary: List Baselines description: List eval baselines (most recent active baseline per suite is what we gate on). operationId: list_baselines_api_v1_detection_proposals_baselines_get security: - HTTPBearer: [] parameters: - name: suite in: query required: false schema: anyOf: - type: string - type: 'null' title: Suite responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/BaselineResponse' title: Response List Baselines Api V1 Detection Proposals Baselines Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - detection_rules - dac summary: Record Baseline description: Record a new eval baseline and deactivate older entries for the same suite. operationId: record_baseline_api_v1_detection_proposals_baselines_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateBaselineRequest' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/BaselineResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/detection-proposals/{proposal_id}: get: tags: - detection_rules - dac summary: Get Proposal description: Get a proposal by id. operationId: get_proposal_api_v1_detection_proposals__proposal_id__get security: - HTTPBearer: [] parameters: - name: proposal_id in: path required: true schema: type: string format: uuid title: Proposal Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ProposalResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/detection-proposals/{proposal_id}/comment: post: tags: - detection_rules - dac summary: Comment On Proposal description: Append a review comment and move the proposal into `in_review`. operationId: comment_on_proposal_api_v1_detection_proposals__proposal_id__comment_post security: - HTTPBearer: [] parameters: - name: proposal_id in: path required: true schema: type: string format: uuid title: Proposal Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReviewCommentRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ProposalResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/detection-proposals/run-eval: post: tags: - detection_rules - dac summary: Run the offline eval harness (`scripts/run_evals.py`) and return the JSON report description: 'Execute the offline eval harness and return its JSON output. This is the "eval-harness regression on save" hook for the in-app rule editor. The harness is deterministic and offline, but takes 5–15s, so the editor surfaces it as an explicit "Propose for review" action rather than firing on every keystroke.' operationId: run_eval_harness_api_v1_detection_proposals_run_eval_post requestBody: content: application/json: schema: $ref: '#/components/schemas/RunEvalRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RunEvalResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/detection-proposals/{proposal_id}/eval: post: tags: - detection_rules - dac summary: Attach Eval Result description: 'Attach the run_evals.py output and compute the gate verdict. Reads the active MITRE accuracy baseline for the tenant (falling back to the platform-wide baseline) and stores ``eval_result.passed=True`` only when MITRE accuracy regression is < ``max_regression_pp``.' operationId: attach_eval_result_api_v1_detection_proposals__proposal_id__eval_post security: - HTTPBearer: [] parameters: - name: proposal_id in: path required: true schema: type: string format: uuid title: Proposal Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/EvalAttachRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ProposalResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/detection-proposals/{proposal_id}/decide: post: tags: - detection_rules - dac summary: Decide Proposal description: Approve or reject a proposal. Approving requires the eval gate to have passed. operationId: decide_proposal_api_v1_detection_proposals__proposal_id__decide_post security: - HTTPBearer: [] parameters: - name: proposal_id in: path required: true schema: type: string format: uuid title: Proposal Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DecisionRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ProposalResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/detection-proposals/{proposal_id}/promote: post: tags: - detection_rules - dac summary: Materialise an approved proposal into the detection_rules table description: 'Promote an approved proposal: create or update the linked detection rule.' operationId: promote_proposal_api_v1_detection_proposals__proposal_id__promote_post security: - HTTPBearer: [] parameters: - name: proposal_id in: path required: true schema: type: string format: uuid title: Proposal Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ProposalResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/detection/tuning: get: tags: - detection summary: Get Tuning Workbench description: 'Project every rule the tenant can tune into a workbench feed. The summary block is computed across the *entire classified population* (not the current page), so the header tiles stay stable as analysts page. Dismissed rules are excluded by default — pass ``include_dismissed=true`` when auditing what''s been hidden.' operationId: get_tuning_workbench_api_v1_detection_tuning_get security: - HTTPBearer: [] parameters: - name: severity in: query required: false schema: anyOf: - type: string - type: 'null' description: Filter by rule severity (info/low/medium/high/critical). title: Severity description: Filter by rule severity (info/low/medium/high/critical). - name: suggestion in: query required: false schema: anyOf: - enum: - disable - add_suppression - raise_threshold - tune_confidence - review_stale - healthy type: string - type: 'null' description: Filter to a single suggestion lane. title: Suggestion description: Filter to a single suggestion lane. - name: search in: query required: false schema: anyOf: - type: string maxLength: 200 - type: 'null' description: Substring match on name/description/category. title: Search description: Substring match on name/description/category. - name: enabled_only in: query required: false schema: type: boolean description: Hide rules whose status != 'active'. default: false title: Enabled Only description: Hide rules whose status != 'active'. - name: include_dismissed in: query required: false schema: type: boolean description: Show rules previously dismissed from the workbench. default: false title: Include Dismissed description: Show rules previously dismissed from the workbench. - name: page in: query required: false schema: type: integer minimum: 1 default: 1 title: Page - name: page_size in: query required: false schema: type: integer maximum: 100 minimum: 1 default: 50 title: Page Size responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TuningResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/detection/tuning/summary: get: tags: - detection summary: Get Tuning Summary description: 'Cheap summary-only endpoint for sidebar badges and the /console dashboard tile.' operationId: get_tuning_summary_api_v1_detection_tuning_summary_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TuningSummary' security: - HTTPBearer: [] /api/v1/detection/tuning/{rule_id}/apply: post: tags: - detection summary: Apply Tuning Endpoint description: 'Mechanically apply a tuning suggestion to a single rule. Supports ``raise_threshold``, ``add_suppression``, ``disable``, and ``acknowledge`` (no-op + audit). Every mutation bumps ``DetectionRule.version`` and writes a ``detection.tuning.apply`` audit log entry. Returns the re-projected entry so the UI can refresh in place.' operationId: apply_tuning_endpoint_api_v1_detection_tuning__rule_id__apply_post security: - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: string format: uuid title: Rule Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ApplyTuningRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TuningEntry' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/detection/tuning/{rule_id}/dismiss: post: tags: - detection summary: Dismiss Tuning Endpoint description: Hide a rule from the default workbench view without changing semantics. operationId: dismiss_tuning_endpoint_api_v1_detection_tuning__rule_id__dismiss_post security: - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: string format: uuid title: Rule Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DismissTuningRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TuningEntry' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/detection/tuning/{rule_id}/auto_tune: post: tags: - detection summary: Set Auto Tune Endpoint description: 'Flip the per-rule ``auto_tune`` opt-in flag. The flag is stored under ``suppression_config.auto_tune`` and is read by future automated tuners — flipping it does *not* trigger any immediate rule mutation.' operationId: set_auto_tune_endpoint_api_v1_detection_tuning__rule_id__auto_tune_post security: - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: string format: uuid title: Rule Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AutoTuneRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TuningEntry' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/federated/backends: get: tags: - federated-search summary: List Federated Backends description: 'List the connector instances that ``POST /search`` would fan out to. Useful for the wizard preview ("you''ll search 1 Splunk + 1 Elastic") and for the SDK to build sensible default ``connector_ids`` lists.' operationId: list_federated_backends_api_v1_federated_backends_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FederatedBackendsResponse' security: - HTTPBearer: [] /api/v1/federated/search: post: tags: - federated-search summary: Federated Search description: 'Run a unified query across every federated-capable connector. Per-backend errors do not fail the call. The response always carries a ``sources[]`` array describing the verdict for each backend that was attempted; the merged ``rows[]`` only contains rows from the ``ok`` sources.' operationId: federated_search_api_v1_federated_search_post requestBody: content: application/json: schema: $ref: '#/components/schemas/FederatedSearchRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FederatedSearchResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/graph/attack-path/{case_id}: get: tags: - graph summary: Get attack path graph for a case description: 'Traverse the knowledge graph from a Case node to reconstruct the full attack path: Case → Alerts → Hosts/Users → IOCs → MITRE Techniques. Falls back to a relational reconstruction (Case → Alerts → Techniques) when the Neo4j graph backend is offline so the demo Attack Path UI keeps working without a graph database deployed.' operationId: get_attack_path_api_v1_graph_attack_path__case_id__get security: - HTTPBearer: [] parameters: - name: case_id in: path required: true schema: type: string title: Case Id - name: max_depth in: query required: false schema: type: integer maximum: 10 minimum: 1 default: 6 title: Max Depth responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AttackPathResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/graph/blast-radius/{entity_type}/{entity_id}: get: tags: - graph summary: Compute blast radius from an entity description: 'Compute the blast radius starting from a Host, User, or IOC node. Returns all entities reachable within `hops` and a severity score.' operationId: get_blast_radius_api_v1_graph_blast_radius__entity_type___entity_id__get security: - HTTPBearer: [] parameters: - name: entity_type in: path required: true schema: type: string title: Entity Type - name: entity_id in: path required: true schema: type: string title: Entity Id - name: hops in: query required: false schema: type: integer maximum: 6 minimum: 1 default: 3 title: Hops responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/BlastRadiusResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/graph/neighbors/{entity_type}/{entity_id}: get: tags: - graph summary: Get immediate graph neighbors of an entity description: Return all nodes directly connected (depth 1) to the specified entity. operationId: get_entity_neighbors_api_v1_graph_neighbors__entity_type___entity_id__get security: - HTTPBearer: [] parameters: - name: entity_type in: path required: true schema: type: string title: Entity Type - name: entity_id in: path required: true schema: type: string title: Entity Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/EntityNeighborsResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/graph/mitre-coverage: get: tags: - graph summary: MITRE ATT&CK technique coverage for tenant description: 'Return MITRE ATT&CK technique coverage aggregated from all tenant alerts. When the Neo4j knowledge graph is unreachable (e.g. in the public demo), this endpoint returns an empty list rather than 503-ing, so the Coverage UI degrades gracefully instead of breaking the whole page.' operationId: get_mitre_coverage_api_v1_graph_mitre_coverage_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/MitreCoverageItem' type: array title: Response Get Mitre Coverage Api V1 Graph Mitre Coverage Get security: - HTTPBearer: [] /api/v1/graph/mitre/coverage: get: tags: - graph summary: MITRE ATT&CK coverage (frontend shape) description: 'Aggregated MITRE coverage in the shape the analyst console expects. The console''s :code:`graph.getMitreCoverage()` call hits this URL and expects ``{ tactics, cells, generatedAt }``. We aggregate the per-technique records returned by the same Neo4j-backed service used by ``/graph/mitre-coverage`` and degrade gracefully (empty set) when the knowledge graph is offline, mirroring that endpoint''s behaviour.' operationId: get_mitre_coverage_compat_api_v1_graph_mitre_coverage_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/MitreCoverageResponse' security: - HTTPBearer: [] /api/v1/graph/entities/host: post: tags: - graph summary: Upsert a Host node in the graph description: Create or update a Host node in the knowledge graph. operationId: upsert_host_api_v1_graph_entities_host_post requestBody: content: application/json: schema: $ref: '#/components/schemas/UpsertHostRequest' required: true responses: '201': description: Successful Response content: application/json: schema: additionalProperties: type: string type: object title: Response Upsert Host Api V1 Graph Entities Host Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/graph/entities/user: post: tags: - graph summary: Upsert a User node in the graph description: Create or update a User node in the knowledge graph. operationId: upsert_user_api_v1_graph_entities_user_post requestBody: content: application/json: schema: $ref: '#/components/schemas/UpsertUserRequest' required: true responses: '201': description: Successful Response content: application/json: schema: additionalProperties: type: string type: object title: Response Upsert User Api V1 Graph Entities User Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/graph/entities/alert: post: tags: - graph summary: Upsert an Alert node and its relationships in the graph description: 'Create or update an Alert node and link it to Host, User, IOC, and Technique nodes. Called automatically after alert creation to keep the graph in sync.' operationId: upsert_alert_graph_api_v1_graph_entities_alert_post requestBody: content: application/json: schema: $ref: '#/components/schemas/UpsertAlertGraphRequest' required: true responses: '201': description: Successful Response content: application/json: schema: additionalProperties: type: string type: object title: Response Upsert Alert Graph Api V1 Graph Entities Alert Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/graph/entities/case: post: tags: - graph summary: Upsert a Case node and link to alerts in the graph description: Create or update a Case node and link it to Alert nodes. operationId: upsert_case_graph_api_v1_graph_entities_case_post requestBody: content: application/json: schema: $ref: '#/components/schemas/UpsertCaseGraphRequest' required: true responses: '201': description: Successful Response content: application/json: schema: additionalProperties: type: string type: object title: Response Upsert Case Graph Api V1 Graph Entities Case Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/playbooks: get: tags: - playbooks summary: List playbooks operationId: list_playbooks_api_v1_playbooks_get parameters: - name: enabled_only in: query required: false schema: type: boolean default: false title: Enabled Only responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - playbooks summary: Create playbook operationId: create_playbook_api_v1_playbooks_post responses: '201': description: Successful Response content: application/json: schema: {} /api/v1/playbooks/runs: get: tags: - playbooks summary: List playbook runs operationId: list_runs_api_v1_playbooks_runs_get parameters: - name: limit in: query required: false schema: type: integer default: 50 title: Limit responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/playbooks/runs/{run_id}: get: tags: - playbooks summary: Get a playbook run operationId: get_run_api_v1_playbooks_runs__run_id__get parameters: - name: run_id in: path required: true schema: type: string title: Run Id responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/playbooks/{playbook_id}: get: tags: - playbooks summary: Get a playbook operationId: get_playbook_api_v1_playbooks__playbook_id__get parameters: - name: playbook_id in: path required: true schema: type: string title: Playbook Id responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' put: tags: - playbooks summary: Update a playbook operationId: update_playbook_api_v1_playbooks__playbook_id__put parameters: - name: playbook_id in: path required: true schema: type: string title: Playbook Id responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - playbooks summary: Delete a playbook operationId: delete_playbook_api_v1_playbooks__playbook_id__delete parameters: - name: playbook_id in: path required: true schema: type: string title: Playbook Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/playbooks/{playbook_id}/run: post: tags: - playbooks summary: Execute a playbook operationId: run_playbook_api_v1_playbooks__playbook_id__run_post parameters: - name: playbook_id in: path required: true schema: type: string title: Playbook Id responses: '202': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/plugins: get: tags: - plugins summary: List Plugins description: List all currently loaded plugins, optionally filtered by type. operationId: list_plugins_api_v1_plugins_get security: - HTTPBearer: [] parameters: - name: plugin_type in: query required: false schema: anyOf: - type: string - type: 'null' title: Plugin Type responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/PluginOut' title: Response List Plugins Api V1 Plugins Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/plugins/discover: post: tags: - plugins summary: Discover Plugins description: Re-scan the plugins directory and load any new plugins found. operationId: discover_plugins_api_v1_plugins_discover_post responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/DiscoverResponse' security: - HTTPBearer: [] /api/v1/plugins/{plugin_id}: get: tags: - plugins summary: Get Plugin description: Get details for a specific plugin. operationId: get_plugin_api_v1_plugins__plugin_id__get security: - HTTPBearer: [] parameters: - name: plugin_id in: path required: true schema: type: string title: Plugin Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/PluginOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - plugins summary: Unload Plugin description: Unload a plugin from memory (does not remove files from disk). operationId: unload_plugin_api_v1_plugins__plugin_id__delete security: - HTTPBearer: [] parameters: - name: plugin_id in: path required: true schema: type: string title: Plugin Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/plugins/{plugin_id}/enable: post: tags: - plugins summary: Enable Plugin description: Enable a loaded plugin. operationId: enable_plugin_api_v1_plugins__plugin_id__enable_post security: - HTTPBearer: [] parameters: - name: plugin_id in: path required: true schema: type: string title: Plugin Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/PluginOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/plugins/{plugin_id}/disable: post: tags: - plugins summary: Disable Plugin description: Disable a loaded plugin (keeps it in memory but blocks invocations). operationId: disable_plugin_api_v1_plugins__plugin_id__disable_post security: - HTTPBearer: [] parameters: - name: plugin_id in: path required: true schema: type: string title: Plugin Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/PluginOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/plugins/{plugin_id}/reload: post: tags: - plugins summary: Reload Plugin description: Unload and re-import a plugin from disk (hot-reload). operationId: reload_plugin_api_v1_plugins__plugin_id__reload_post security: - HTTPBearer: [] parameters: - name: plugin_id in: path required: true schema: type: string title: Plugin Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/PluginOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/plugins/{plugin_id}/run: post: tags: - plugins summary: Run Plugin description: 'Directly invoke a plugin. Supports enrichers, actions, and connectors.' operationId: run_plugin_api_v1_plugins__plugin_id__run_post security: - HTTPBearer: [] parameters: - name: plugin_id in: path required: true schema: type: string title: Plugin Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RunRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RunResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/community/plugins/publish: post: tags: - community summary: Publish Plugin description: Submit a signed plugin tarball for community review. operationId: publish_plugin_api_v1_community_plugins_publish_post responses: '201': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Publish Plugin Api V1 Community Plugins Publish Post security: - HTTPBearer: [] /api/v1/community/plugins: get: tags: - community summary: List Community Plugins description: Browse approved community plugins. operationId: list_community_plugins_api_v1_community_plugins_get parameters: - name: status in: query required: false schema: anyOf: - type: string - type: 'null' title: Status - name: plugin_type in: query required: false schema: anyOf: - type: string - type: 'null' title: Plugin Type - name: tags in: query required: false schema: anyOf: - type: string - type: 'null' description: Comma-separated tags title: Tags description: Comma-separated tags - name: sort in: query required: false schema: type: string pattern: ^(install_count|rating|submitted_at|name)$ default: install_count title: Sort - name: order in: query required: false schema: type: string pattern: ^(asc|desc)$ default: desc title: Order - name: page in: query required: false schema: type: integer minimum: 1 default: 1 title: Page - name: page_size in: query required: false schema: type: integer maximum: 100 minimum: 1 default: 20 title: Page Size responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CommunityPluginListOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/community/plugins/{plugin_id}: get: tags: - community summary: Get Community Plugin description: Get community plugin detail. operationId: get_community_plugin_api_v1_community_plugins__plugin_id__get parameters: - name: plugin_id in: path required: true schema: type: string title: Plugin Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CommunityPluginOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/community/plugins/{plugin_id}/install: post: tags: - community summary: Install Community Plugin description: Install a community plugin to the current instance. operationId: install_community_plugin_api_v1_community_plugins__plugin_id__install_post security: - HTTPBearer: [] parameters: - name: plugin_id in: path required: true schema: type: string title: Plugin Id responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: type: string title: Response Install Community Plugin Api V1 Community Plugins Plugin Id Install Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/community/plugins/{plugin_id}/rate: post: tags: - community summary: Rate Community Plugin description: Rate a community plugin. operationId: rate_community_plugin_api_v1_community_plugins__plugin_id__rate_post security: - HTTPBearer: [] parameters: - name: plugin_id in: path required: true schema: type: string title: Plugin Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RatingIn' responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response Rate Community Plugin Api V1 Community Plugins Plugin Id Rate Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/community/plugins/{plugin_id}/review: put: tags: - community summary: Review Community Plugin description: 'Admin: approve or reject a plugin submission.' operationId: review_community_plugin_api_v1_community_plugins__plugin_id__review_put security: - HTTPBearer: [] parameters: - name: plugin_id in: path required: true schema: type: string title: Plugin Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReviewAction' responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: type: string title: Response Review Community Plugin Api V1 Community Plugins Plugin Id Review Put '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/community/detections/publish: post: tags: - community summary: Publish Detection description: Submit a Sigma detection rule for community review. operationId: publish_detection_api_v1_community_detections_publish_post requestBody: content: text/plain: schema: type: string title: Content required: true responses: '201': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Publish Detection Api V1 Community Detections Publish Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/community/detections: get: tags: - community summary: List Community Detections description: Browse community Sigma detection rules with pagination and filtering. operationId: list_community_detections_api_v1_community_detections_get parameters: - name: page in: query required: false schema: type: integer minimum: 1 default: 1 title: Page - name: page_size in: query required: false schema: type: integer maximum: 100 minimum: 1 default: 20 title: Page Size - name: search in: query required: false schema: anyOf: - type: string - type: 'null' title: Search - name: logsource_category in: query required: false schema: anyOf: - type: string - type: 'null' title: Logsource Category - name: logsource_product in: query required: false schema: anyOf: - type: string - type: 'null' title: Logsource Product - name: level in: query required: false schema: anyOf: - type: string - type: 'null' title: Level - name: sort_by in: query required: false schema: type: string pattern: ^(install_count|rating|name)$ default: install_count title: Sort By responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response List Community Detections Api V1 Community Detections Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/community/detections/{detection_id}: get: tags: - community summary: Get Community Detection description: Get Sigma rule detail including full YAML content (sigma_yaml field). operationId: get_community_detection_api_v1_community_detections__detection_id__get parameters: - name: detection_id in: path required: true schema: type: string title: Detection Id responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response Get Community Detection Api V1 Community Detections Detection Id Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/community/detections/{detection_id}/install: post: tags: - community summary: Install Community Detection description: Install a community detection rule to the tenant. operationId: install_community_detection_api_v1_community_detections__detection_id__install_post security: - HTTPBearer: [] parameters: - name: detection_id in: path required: true schema: type: string title: Detection Id responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: type: string title: Response Install Community Detection Api V1 Community Detections Detection Id Install Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/community/playbooks/submit: post: tags: - community summary: Submit Playbook description: Submit a community playbook. operationId: submit_playbook_api_v1_community_playbooks_submit_post requestBody: content: application/json: schema: additionalProperties: true type: object title: Definition required: true responses: '201': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Submit Playbook Api V1 Community Playbooks Submit Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/community/playbooks: get: tags: - community summary: List Community Playbooks description: Browse approved community playbooks with optional search and sort. operationId: list_community_playbooks_api_v1_community_playbooks_get parameters: - name: page in: query required: false schema: type: integer minimum: 1 default: 1 title: Page - name: page_size in: query required: false schema: type: integer maximum: 100 minimum: 1 default: 20 title: Page Size - name: search in: query required: false schema: anyOf: - type: string - type: 'null' title: Search - name: sort_by in: query required: false schema: type: string pattern: ^(install_count|rating|name)$ default: install_count title: Sort By responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response List Community Playbooks Api V1 Community Playbooks Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/community/playbooks/{playbook_id}/install: post: tags: - community summary: Install Community Playbook description: Install a community playbook to the tenant. operationId: install_community_playbook_api_v1_community_playbooks__playbook_id__install_post security: - HTTPBearer: [] parameters: - name: playbook_id in: path required: true schema: type: string title: Playbook Id responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: type: string title: Response Install Community Playbook Api V1 Community Playbooks Playbook Id Install Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/community/playbooks/{playbook_id}/curate: put: tags: - community summary: Curate Community Playbook description: 'Admin: approve or reject a playbook submission.' operationId: curate_community_playbook_api_v1_community_playbooks__playbook_id__curate_put security: - HTTPBearer: [] parameters: - name: playbook_id in: path required: true schema: type: string title: Playbook Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReviewAction' responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: type: string title: Response Curate Community Playbook Api V1 Community Playbooks Playbook Id Curate Put '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/marketplace: get: tags: - marketplace summary: List Marketplace description: Return the marketplace index with the same filters the UI exposes. operationId: list_marketplace_api_v1_marketplace_get security: - HTTPBearer: [] parameters: - name: type in: query required: false schema: anyOf: - enum: - detection - playbook - plugin type: string - type: 'null' title: Type - name: mitre in: query required: false schema: anyOf: - type: string - type: 'null' description: MITRE ATT&CK technique ID, e.g. T1078 or T1078.004 title: Mitre description: MITRE ATT&CK technique ID, e.g. T1078 or T1078.004 - name: severity in: query required: false schema: anyOf: - type: string - type: 'null' title: Severity - name: category in: query required: false schema: anyOf: - type: string - type: 'null' title: Category - name: source in: query required: false schema: anyOf: - enum: - core - community type: string - type: 'null' title: Source - name: sdk in: query required: false schema: anyOf: - enum: - python - go - both type: string - type: 'null' title: Sdk - name: search in: query required: false schema: anyOf: - type: string maxLength: 200 - type: 'null' title: Search responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/MarketplaceListResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/marketplace/install: post: tags: - marketplace summary: Install Marketplace Item description: 'Activate a marketplace item for the caller''s tenant. For core (on-disk) items this records that the item is "enabled" for the tenant — the underlying detection/playbook/plugin file is already present on the AiSOC instance and is read straight from disk by the relevant subsystem. The install marker is what the UI needs in order to show ``✓ Installed`` and what tenants can later disable.' operationId: install_marketplace_item_api_v1_marketplace_install_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/InstallRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/InstallResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - marketplace summary: Uninstall Marketplace Item description: Remove a previously installed marketplace item from the tenant. operationId: uninstall_marketplace_item_api_v1_marketplace_install_delete security: - HTTPBearer: [] parameters: - name: type in: query required: true schema: enum: - detection - playbook - plugin type: string title: Type - name: id in: query required: true schema: type: string title: Id responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response Uninstall Marketplace Item Api V1 Marketplace Install Delete '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/marketplace/installed: get: tags: - marketplace summary: List Installed description: List all marketplace items installed for the caller's tenant. operationId: list_installed_api_v1_marketplace_installed_get responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response List Installed Api V1 Marketplace Installed Get security: - HTTPBearer: [] /api/v1/marketplace/mitre: get: tags: - marketplace summary: Mitre Coverage description: 'Return the MITRE ATT&CK coverage block from the marketplace index. Useful for the marketplace UI to render its MITRE filter without walking every item on the client.' operationId: mitre_coverage_api_v1_marketplace_mitre_get responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Mitre Coverage Api V1 Marketplace Mitre Get security: - HTTPBearer: [] /api/v1/rbac/permissions: get: tags: - rbac summary: List Permissions description: List all available permissions. operationId: list_permissions_api_v1_rbac_permissions_get security: - HTTPBearer: [] parameters: - name: category in: query required: false schema: anyOf: - type: string - type: 'null' title: Category responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/PermissionOut' title: Response List Permissions Api V1 Rbac Permissions Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/rbac/roles: get: tags: - rbac summary: List Roles description: List all roles for the current tenant. operationId: list_roles_api_v1_rbac_roles_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/RoleOut' type: array title: Response List Roles Api V1 Rbac Roles Get security: - HTTPBearer: [] post: tags: - rbac summary: Create Role description: Create a custom role for the current tenant. operationId: create_role_api_v1_rbac_roles_post requestBody: content: application/json: schema: $ref: '#/components/schemas/RoleIn' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RoleOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/rbac/roles/{role_id}: get: tags: - rbac summary: Get Role operationId: get_role_api_v1_rbac_roles__role_id__get security: - HTTPBearer: [] parameters: - name: role_id in: path required: true schema: type: string format: uuid title: Role Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RoleOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' patch: tags: - rbac summary: Update Role operationId: update_role_api_v1_rbac_roles__role_id__patch security: - HTTPBearer: [] parameters: - name: role_id in: path required: true schema: type: string format: uuid title: Role Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RoleUpdate' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RoleOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - rbac summary: Delete Role operationId: delete_role_api_v1_rbac_roles__role_id__delete security: - HTTPBearer: [] parameters: - name: role_id in: path required: true schema: type: string format: uuid title: Role Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/rbac/users/{user_id}/roles: get: tags: - rbac summary: Get User Roles description: List roles assigned to a user within the current tenant. operationId: get_user_roles_api_v1_rbac_users__user_id__roles_get security: - HTTPBearer: [] parameters: - name: user_id in: path required: true schema: type: string format: uuid title: User Id responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/UserRoleOut' title: Response Get User Roles Api V1 Rbac Users User Id Roles Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - rbac summary: Assign Role description: Assign a role to a user. operationId: assign_role_api_v1_rbac_users__user_id__roles_post security: - HTTPBearer: [] parameters: - name: user_id in: path required: true schema: type: string format: uuid title: User Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UserRoleAssignment' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/UserRoleOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/rbac/users/{user_id}/roles/{role_id}: delete: tags: - rbac summary: Revoke Role description: Revoke a role from a user. operationId: revoke_role_api_v1_rbac_users__user_id__roles__role_id__delete security: - HTTPBearer: [] parameters: - name: user_id in: path required: true schema: type: string format: uuid title: User Id - name: role_id in: path required: true schema: type: string format: uuid title: Role Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/audit: get: tags: - audit summary: List Audit Events description: Return a paginated, tenant-scoped audit trail. operationId: list_audit_events_api_v1_audit_get security: - HTTPBearer: [] parameters: - name: page in: query required: false schema: type: integer minimum: 1 default: 1 title: Page - name: page_size in: query required: false schema: type: integer maximum: 200 minimum: 1 default: 50 title: Page Size - name: action in: query required: false schema: anyOf: - type: string - type: 'null' description: Filter by action prefix, e.g. 'cases:' title: Action description: Filter by action prefix, e.g. 'cases:' - name: resource in: query required: false schema: anyOf: - type: string - type: 'null' title: Resource - name: actor_id in: query required: false schema: anyOf: - type: string format: uuid - type: 'null' title: Actor Id - name: search in: query required: false schema: anyOf: - type: string - type: 'null' description: Search actor_email or action title: Search description: Search actor_email or action responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AuditListResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/audit/export: get: tags: - audit summary: Export the (filtered) audit trail as CSV or print-ready HTML description: "Return the filtered audit trail as a downloadable artefact.\n\n\ * ``format=csv`` (default) — RFC 4180 CSV, suitable for SIEM ingest\n and\ \ compliance binders.\n* ``format=html`` — self-contained HTML the browser\ \ can save to PDF.\n\nThe same filters as ``GET /audit`` apply, so the exported\ \ bundle\nmatches what the analyst is looking at in the UI. A hard ``limit``\n\ of 10 000 rows keeps a single export bounded — narrow the filters\nfor very\ \ long-running tenants." operationId: export_audit_events_api_v1_audit_export_get security: - HTTPBearer: [] parameters: - name: format in: query required: false schema: type: string pattern: ^(csv|html)$ default: csv title: Format - name: action in: query required: false schema: anyOf: - type: string - type: 'null' description: Filter by action prefix, e.g. 'cases:' title: Action description: Filter by action prefix, e.g. 'cases:' - name: resource in: query required: false schema: anyOf: - type: string - type: 'null' title: Resource - name: actor_id in: query required: false schema: anyOf: - type: string format: uuid - type: 'null' title: Actor Id - name: search in: query required: false schema: anyOf: - type: string - type: 'null' description: Search actor_email or action title: Search description: Search actor_email or action - name: limit in: query required: false schema: type: integer maximum: 10000 minimum: 1 default: 10000 title: Limit responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/compliance/frameworks: get: tags: - compliance summary: List frameworks and controls operationId: list_frameworks_api_v1_compliance_frameworks_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FrameworksResponse' /api/v1/compliance/frameworks/{framework_id}/controls: get: tags: - compliance summary: List controls for a framework operationId: list_framework_controls_api_v1_compliance_frameworks__framework_id__controls_get parameters: - name: framework_id in: path required: true schema: type: string title: Framework Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ControlsResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/compliance/evidence/collect: post: tags: - compliance summary: Trigger evidence collection job operationId: trigger_evidence_collection_api_v1_compliance_evidence_collect_post requestBody: content: application/json: schema: $ref: '#/components/schemas/CollectJobRequest' required: true responses: '202': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CollectJobResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/compliance/evidence: post: tags: - compliance summary: Collect evidence item operationId: collect_evidence_api_v1_compliance_evidence_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CollectEvidenceRequest' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/EvidenceResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' get: tags: - compliance summary: List evidence items operationId: list_evidence_api_v1_compliance_evidence_get security: - HTTPBearer: [] parameters: - name: framework in: query required: false schema: anyOf: - type: string - type: 'null' title: Framework - name: control_id in: query required: false schema: anyOf: - type: string - type: 'null' title: Control Id - name: case_id in: query required: false schema: anyOf: - type: string format: uuid - type: 'null' title: Case Id - name: status in: query required: false schema: anyOf: - type: string - type: 'null' title: Status - name: limit in: query required: false schema: type: integer maximum: 1000 minimum: 1 default: 100 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/EvidenceResponse' title: Response List Evidence Api V1 Compliance Evidence Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/compliance/evidence/{evidence_id}: get: tags: - compliance summary: Get evidence item operationId: get_evidence_api_v1_compliance_evidence__evidence_id__get security: - HTTPBearer: [] parameters: - name: evidence_id in: path required: true schema: type: string format: uuid title: Evidence Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/EvidenceResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/compliance/evidence/{evidence_id}/review: post: tags: - compliance summary: Accept or reject evidence operationId: review_evidence_api_v1_compliance_evidence__evidence_id__review_post security: - HTTPBearer: [] parameters: - name: evidence_id in: path required: true schema: type: string format: uuid title: Evidence Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ReviewEvidenceRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/EvidenceResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/compliance/report: get: tags: - compliance summary: Generate compliance posture report operationId: compliance_report_api_v1_compliance_report_get security: - HTTPBearer: [] parameters: - name: framework in: query required: false schema: anyOf: - type: string - type: 'null' description: Filter to a single framework. title: Framework description: Filter to a single framework. responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/CompliancePosture' title: Response Compliance Report Api V1 Compliance Report Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/metrics/dashboard: get: tags: - metrics summary: Get Dashboard Metrics description: Return aggregated KPI metrics for the dashboard overview tiles. operationId: get_dashboard_metrics_api_v1_metrics_dashboard_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/DashboardMetrics' security: - HTTPBearer: [] /api/v1/metrics/soc: get: tags: - metrics summary: Get Soc Metrics description: "Return SOC-level KPIs, ATT&CK heatmap, and confidence calibration\ \ curve.\n\nTier 1.4 metrics:\n - MTTD, MTTR, MTTC, FPR, escalation rate,\ \ analyst overrides\n - ATT&CK technique × tactic heatmap\n - Confidence\ \ calibration over time (reliability curve)" operationId: get_soc_metrics_api_v1_metrics_soc_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/SOCMetrics' security: - HTTPBearer: [] /api/v1/metrics/alerts/trend: get: tags: - metrics summary: Get Alert Trend description: Return alert count trend data bucketed by time period. operationId: get_alert_trend_api_v1_metrics_alerts_trend_get security: - HTTPBearer: [] parameters: - name: period in: query required: false schema: type: string default: 24h title: Period responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response Get Alert Trend Api V1 Metrics Alerts Trend Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/metrics/funnel: get: tags: - metrics summary: Get Funnel Metrics description: 'Return the live tenant funnel for the SOC Console (v1.5). Funnel: events_of_interest → correlation_instances → alerts_generated → analyst_queue_depth, plus efficiency ratios and MITRE coverage. ``deltas`` compares the current window to the immediately preceding window of the same length (e.g. for ``period=24h`` we compare to the 24h ending 24h ago). Values are percentage changes rounded to two decimals; a delta of ``0.0`` means "no meaningful baseline" (the previous window was empty).' operationId: get_funnel_metrics_api_v1_metrics_funnel_get security: - HTTPBearer: [] parameters: - name: period in: query required: false schema: type: string pattern: ^(1h|24h|7d|30d)$ default: 24h title: Period responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FunnelMetrics' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/health/pipeline: get: tags: - health summary: Get Pipeline Health description: 'Return a 5-stage health snapshot of the SOC pipeline for the tenant. Stages: ``ingest → normalize → fuse → correlate → alert``. See the module docstring for what each cell measures and why some columns are intentionally ``0`` until deeper instrumentation lands. The window for latency / backlog computations is the last hour. The ``status`` ladder is ``unknown | green | yellow | red`` and follows the same convention as ``app.services.connector_freshness``.' operationId: get_pipeline_health_api_v1_health_pipeline_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/PipelineHealth' security: - HTTPBearer: [] /api/v1/insights/soc: get: tags: - insights summary: SOC Insights dashboard aggregate (T3.1) description: 'Return the seven-tile SOC Insights payload for the tenant. Tenant scoping is enforced by ``current_user.tenant_id`` plus an explicit ``tenant_id`` predicate in every aggregate, so the payload is safe to render for any role that can read the dashboard.' operationId: get_soc_insights_api_v1_insights_soc_get security: - HTTPBearer: [] parameters: - name: window in: query required: false schema: enum: - 24h - 7d - 30d type: string description: Rolling window. One of 24h, 7d, 30d. default: 24h title: Window description: Rolling window. One of 24h, 7d, 30d. responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/SOCInsightsResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/sla/metrics: get: tags: - sla summary: Get Sla Metrics description: Return aggregated MTTD / MTTR / MTTC metrics for the tenant. operationId: get_sla_metrics_api_v1_sla_metrics_get security: - HTTPBearer: [] parameters: - name: days in: query required: false schema: type: integer maximum: 365 minimum: 1 description: Look-back window in days default: 30 title: Days description: Look-back window in days responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/sla/kpi-targets: get: tags: - sla summary: Get Kpi Bar Targets description: Return merged 2026 KPI bar targets (published defaults plus tenant ``settings.kpi_bar``). operationId: get_kpi_bar_targets_api_v1_sla_kpi_targets_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/KpiBarTargetsOut' security: - HTTPBearer: [] put: tags: - sla summary: Put Kpi Bar Targets description: Patch tenant KPI bar targets; unspecified fields keep previous values. operationId: put_kpi_bar_targets_api_v1_sla_kpi_targets_put requestBody: content: application/json: schema: $ref: '#/components/schemas/KpiBarTargetsUpdate' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/KpiBarTargetsOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/sla/config: get: tags: - sla summary: Get Sla Config description: Return per-severity SLA configuration for the tenant. operationId: get_sla_config_api_v1_sla_config_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/SLAConfigOut' type: array title: Response Get Sla Config Api V1 Sla Config Get security: - HTTPBearer: [] /api/v1/sla/config/{severity}: put: tags: - sla summary: Update Sla Config description: Upsert SLA targets for a given severity. operationId: update_sla_config_api_v1_sla_config__severity__put security: - HTTPBearer: [] parameters: - name: severity in: path required: true schema: type: string title: Severity requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SLAConfigUpdate' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/SLAConfigOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/sla/events: post: tags: - sla summary: Record Sla Event description: Record a lifecycle event (detected/acknowledged/resolved/closed) for an alert. operationId: record_sla_event_api_v1_sla_events_post requestBody: content: application/json: schema: $ref: '#/components/schemas/SLAEventCreate' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/SLAEventOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/investigations: get: tags: - investigations summary: List Runs description: List recent investigation runs for the caller's tenant. operationId: list_runs_api_v1_investigations_get security: - HTTPBearer: [] parameters: - name: case_id in: query required: false schema: anyOf: - type: string - type: 'null' description: Filter by external case id title: Case Id description: Filter by external case id - name: status in: query required: false schema: anyOf: - type: string - type: 'null' description: 'Filter by status: running | completed | failed' title: Status description: 'Filter by status: running | completed | failed' - name: limit in: query required: false schema: type: integer maximum: 200 minimum: 1 default: 50 title: Limit responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/RunSummary' title: Response List Runs Api V1 Investigations Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/investigations/costs/aggregate: get: tags: - investigations summary: Aggregate Costs description: 'Aggregate LLM spend across investigation runs for this tenant. Joins ``aisoc_run_costs`` against ``investigation_runs`` on ``run_id`` and filters by ``investigation_runs.tenant_id``. We deliberately do NOT filter on ``aisoc_run_costs.tenant_id`` directly: the agents service writes whatever ``tenant_id`` string the request carried (e.g. the slug ``"default"``), which need not match the API-side UUID. Anchoring on the run''s canonical tenant column keeps the answer correct regardless of how the cost row was tagged, and cannot leak across tenants because ``investigation_runs`` is RLS-bound and we re-filter explicitly. Uses Postgres ``GROUPING SETS`` to compute per-model rows and the grand total in one round-trip; ``COUNT(DISTINCT run_id)`` then yields a correct run count for both groupings (a naive ``SUM(runs)`` across models would double-count runs that touched more than one model).' operationId: aggregate_costs_api_v1_investigations_costs_aggregate_get security: - HTTPBearer: [] parameters: - name: window_days in: query required: false schema: type: integer maximum: 365 minimum: 1 description: Look-back window in days (anchored on run start time) default: 30 title: Window Days description: Look-back window in days (anchored on run start time) responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CostAggregateResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/investigations/{run_id}: get: tags: - investigations summary: Get Run description: Run summary plus count of attached events and artifacts. operationId: get_run_api_v1_investigations__run_id__get security: - HTTPBearer: [] parameters: - name: run_id in: path required: true schema: type: string format: uuid title: Run Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RunDetail' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/investigations/{run_id}/events: get: tags: - investigations summary: List Events description: 'Paginated event stream for a run. The ``since`` cursor lets clients tail the stream — pass the previously returned ``next_seq`` to fetch the next page without overlap.' operationId: list_events_api_v1_investigations__run_id__events_get security: - HTTPBearer: [] parameters: - name: run_id in: path required: true schema: type: string format: uuid title: Run Id - name: since in: query required: false schema: anyOf: - type: integer minimum: 0 - type: 'null' description: Return only events with seq strictly greater than this value (long-poll) title: Since description: Return only events with seq strictly greater than this value (long-poll) - name: limit in: query required: false schema: type: integer maximum: 1000 minimum: 1 default: 200 title: Limit responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/EventListResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/investigations/{run_id}/replay: get: tags: - investigations summary: Replay Run description: 'Return the full ordered event list for a run. Bounded by ``max_events`` to keep responses sane; runs that exceed the bound should fall back to the paginated ``/events`` endpoint.' operationId: replay_run_api_v1_investigations__run_id__replay_get security: - HTTPBearer: [] parameters: - name: run_id in: path required: true schema: type: string format: uuid title: Run Id - name: max_events in: query required: false schema: type: integer maximum: 50000 minimum: 1 default: 10000 title: Max Events responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/EventOut' title: Response Replay Run Api V1 Investigations Run Id Replay Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/investigations/{run_id}/explain: get: tags: - investigations summary: Explain Step description: 'Return prompt + response + evidence for a single step. Renders three events for context: the previous decision that led into this step, the focal event, and the next decision. All artifacts attached to the focal event are inlined so the auditor sees the literal LLM transcript.' operationId: explain_step_api_v1_investigations__run_id__explain_get security: - HTTPBearer: [] parameters: - name: run_id in: path required: true schema: type: string format: uuid title: Run Id - name: step in: query required: true schema: type: integer minimum: 0 description: Event seq to explain title: Step description: Event seq to explain responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ExplainResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/investigations/{run_id}/artifacts: get: tags: - investigations summary: List Artifacts operationId: list_artifacts_api_v1_investigations__run_id__artifacts_get security: - HTTPBearer: [] parameters: - name: run_id in: path required: true schema: type: string format: uuid title: Run Id responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/ArtifactSummary' title: Response List Artifacts Api V1 Investigations Run Id Artifacts Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/investigations/{run_id}/artifacts/{artifact_id}: get: tags: - investigations summary: Get Artifact operationId: get_artifact_api_v1_investigations__run_id__artifacts__artifact_id__get security: - HTTPBearer: [] parameters: - name: run_id in: path required: true schema: type: string format: uuid title: Run Id - name: artifact_id in: path required: true schema: type: string format: uuid title: Artifact Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ArtifactDetail' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/investigations/{run_id}/timeline: get: tags: - investigations summary: Get Timeline description: "Return a scrubbable investigation timeline with decision-provenance\ \ annotations.\n\nEach node carries:\n* ``decision`` — structured provenance\ \ (reason, confidence, next phase,\n tool name/args/result) extracted from\ \ the event ``payload``.\n* ``has_artifact`` — whether a detailed transcript\ \ artifact is attached.\n* ``diff_vs_prev_attempt`` — one-line diff for repeated\ \ steps so analysts\n can see how the agent corrected itself across retry\ \ attempts.\n\nThe response is bounded at 10 000 events. Use the paginated\ \ ``/events``\nendpoint for runs that exceed this." operationId: get_timeline_api_v1_investigations__run_id__timeline_get security: - HTTPBearer: [] parameters: - name: run_id in: path required: true schema: type: string format: uuid title: Run Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/app__api__v1__endpoints__investigations__TimelineResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/investigations/{run_id}/close: post: tags: - investigations summary: Close Investigation description: 'Close an investigation run and persist an auto-generated summary artifact. Idempotent: if the run is already closed a summary artifact is still generated and returned (useful for re-generating the PDF). Status transitions: ``running | completed | failed`` → ``closed``' operationId: close_investigation_api_v1_investigations__run_id__close_post security: - HTTPBearer: [] parameters: - name: run_id in: path required: true schema: type: string format: uuid title: Run Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CloseRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ClosedSummary' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/investigations/{run_id}/summary.pdf: get: tags: - investigations summary: Export Summary Pdf description: 'Stream the investigation summary as a PDF. Looks for the most recent ``investigation-summary`` artifact. If none exists yet the caller should ``POST /close`` first. The PDF is generated server-side using pure-Python ``reportlab`` so there are no browser or headless-Chrome dependencies.' operationId: export_summary_pdf_api_v1_investigations__run_id__summary_pdf_get security: - HTTPBearer: [] parameters: - name: run_id in: path required: true schema: type: string format: uuid title: Run Id responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/identity/effective-permissions/providers: get: tags: - identity-effective-permissions summary: List supported effective-permissions providers description: 'Return ``{"providers": [{"name", "coverage"}, ...]}``. The UI calls this once on mount to render the provider switcher and to grey out scaffolded providers.' operationId: list_providers_api_v1_identity_effective_permissions_providers_get responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response List Providers Api V1 Identity Effective Permissions Providers Get security: - HTTPBearer: [] /api/v1/identity/{principal_id}/effective-permissions: get: tags: - identity-effective-permissions summary: Resolve effective permissions for a principal description: 'Resolve and return the effective-permissions envelope. Cache write is dispatched as a FastAPI ``BackgroundTask`` so the request returns as soon as the resolver finishes — the UI never waits on Neo4j.' operationId: get_effective_permissions_api_v1_identity__principal_id__effective_permissions_get security: - HTTPBearer: [] parameters: - name: principal_id in: path required: true schema: type: string title: Principal Id - name: provider in: query required: true schema: type: string description: Provider to resolve against (aws|azure|gcp|okta|gws). title: Provider description: Provider to resolve against (aws|azure|gcp|okta|gws). - name: snapshot_b64 in: query required: false schema: anyOf: - type: string - type: 'null' description: Optional base64-encoded JSON snapshot for dry-run resolution. Only honoured when AISOC_ALLOW_INLINE_SNAPSHOT=1 is set. title: Snapshot B64 description: Optional base64-encoded JSON snapshot for dry-run resolution. Only honoured when AISOC_ALLOW_INLINE_SNAPSHOT=1 is set. responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response Get Effective Permissions Api V1 Identity Principal Id Effective Permissions Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/costs/dashboard: get: tags: - costs summary: LLM spend, action counts, top-cost cases, and BYOK savings for the tenant description: "Return a deterministic snapshot of cost, activity, and BYOK savings.\n\ \nThe response covers the rolling ``window_days``-long window ending at\n\ ``now()`` (UTC) and includes:\n\n* **headline** — total spend / tokens / calls\ \ / runs and average\n cost-per-run across the window.\n* **daily_costs**\ \ — per-day buckets so the UI can plot a trend line.\n* **by_model** — spend,\ \ tokens, runs, and average latency per model\n with the imputed public-list\ \ cost for context.\n* **top_cases** — the most expensive ``case_id`` values,\ \ the closest\n proxy AiSOC has for \"top-cost playbook runs\" since each\ \ playbook\n run lives under a case (no separate ``playbook_runs`` table).\n\ * **action_counts** — ``audit_log`` action distribution so operators\n can\ \ see how much SOC activity their LLM spend is buying.\n* **byok_savings**\ \ — imputed delta between recorded cost and public\n list pricing. ``is_byok_active``\ \ reflects whether the live LLM\n provider is loopback / private (per ``/llm/status``).\n\ \nTenant scoping is enforced by ``TenantDBSession`` (Postgres RLS sets\n``app.current_tenant_id``)\ \ plus an explicit ``tenant_id`` predicate in\nthe underlying query, so the\ \ same payload is safe to render for any\nrole with ``reports:read``." operationId: get_cost_dashboard_api_v1_costs_dashboard_get security: - HTTPBearer: [] parameters: - name: window_days in: query required: false schema: type: integer maximum: 365 minimum: 1 description: Rolling window in days. Counts back from now() (UTC). Defaults to the last 30 days; capped at 365. default: 30 title: Window Days description: Rolling window in days. Counts back from now() (UTC). Defaults to the last 30 days; capped at 365. responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CostDashboard' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/push/public-key: get: tags: - push summary: Get Public Key description: 'Return the VAPID public key the PWA needs to subscribe. Public on purpose: the key is an application-server identifier, not a secret. Keeping it unauthenticated lets the service worker fetch it on install before the user has logged in.' operationId: get_public_key_api_v1_push_public_key_get responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Get Public Key Api V1 Push Public Key Get /api/v1/push/subscribe: post: tags: - push summary: Subscribe description: Register a PushSubscription for the authenticated user. operationId: subscribe_api_v1_push_subscribe_post requestBody: content: application/json: schema: additionalProperties: true type: object title: Body required: true responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Subscribe Api V1 Push Subscribe Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/push/unsubscribe: post: tags: - push summary: Unsubscribe description: Remove a PushSubscription for the authenticated user. operationId: unsubscribe_api_v1_push_unsubscribe_post requestBody: content: application/json: schema: additionalProperties: true type: object title: Body required: true responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Unsubscribe Api V1 Push Unsubscribe Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/push/test: post: tags: - push summary: Test Notify description: 'Send a test notification to the authenticated user''s devices. Useful for the PWA settings screen "send test" button.' operationId: test_notify_api_v1_push_test_post requestBody: content: application/json: schema: anyOf: - additionalProperties: true type: object - type: 'null' title: Body responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Test Notify Api V1 Push Test Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/oncall: get: tags: - responder - oncall summary: List Oncall description: 'List on-call status for everyone in the tenant. The PWA paging UI lights up everyone marked ``available`` first, then ``busy`` (so the next-best person is one tap away), and finally everyone else for context.' operationId: list_oncall_api_v1_oncall_get security: - HTTPBearer: [] parameters: - name: status in: query required: false schema: anyOf: - type: string - type: 'null' title: Status responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/OnCallListResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/oncall/me: get: tags: - responder - oncall summary: My Oncall operationId: my_oncall_api_v1_oncall_me_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/OnCallEntry' security: - HTTPBearer: [] put: tags: - responder - oncall summary: Update My Oncall description: 'Set my own on-call status. Use ``snoozed`` with ``snooze_minutes`` to defer paging temporarily; the PWA shows a countdown and the agent uses it to skip you for that window.' operationId: update_my_oncall_api_v1_oncall_me_put requestBody: content: application/json: schema: $ref: '#/components/schemas/OnCallUpdateRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/OnCallEntry' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/approvals: get: tags: - responder - approvals summary: List Approvals description: 'List approvals for the current tenant. Defaults to ``status=pending`` so the PWA inbox view is fast. Set ``mine=true`` to only show approvals routed specifically to the current user.' operationId: list_approvals_api_v1_approvals_get security: - HTTPBearer: [] parameters: - name: page in: query required: false schema: type: integer minimum: 1 default: 1 title: Page - name: page_size in: query required: false schema: type: integer maximum: 200 minimum: 1 default: 25 title: Page Size - name: status in: query required: false schema: anyOf: - type: string - type: 'null' default: pending title: Status - name: mine in: query required: false schema: type: boolean default: false title: Mine - name: risk_level in: query required: false schema: anyOf: - type: string - type: 'null' title: Risk Level responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ApprovalListResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - responder - approvals summary: Create Approval description: 'Create a new approval request. The agents service calls this when it hits a high-risk step that requires human sign-off. We persist it, then fan-out a Web Push notification via the realtime service so the PWA buzzes the right on-call analyst.' operationId: create_approval_api_v1_approvals_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ApprovalCreateRequest' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ApprovalResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/approvals/{approval_id}: get: tags: - responder - approvals summary: Get Approval operationId: get_approval_api_v1_approvals__approval_id__get security: - HTTPBearer: [] parameters: - name: approval_id in: path required: true schema: type: string format: uuid title: Approval Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ApprovalResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/approvals/{approval_id}/decide: post: tags: - responder - approvals summary: Decide Approval description: 'Approve or deny a pending approval. Idempotent only on the same decision: re-approving an already approved request returns the row unchanged; trying to flip an approved row to denied (or vice versa) is a 409.' operationId: decide_approval_api_v1_approvals__approval_id__decide_post security: - HTTPBearer: [] parameters: - name: approval_id in: path required: true schema: type: string format: uuid title: Approval Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ApprovalDecisionRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ApprovalResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/passkeys/register/begin: post: tags: - responder - passkeys summary: Passkey Register Begin description: 'Start passkey enrollment for the currently logged-in user. Returns a JSON payload directly suitable for ``navigator.credentials.create({ publicKey: })`` after the standard Base64URL-decoding of the binary fields.' operationId: passkey_register_begin_api_v1_passkeys_register_begin_post requestBody: content: application/json: schema: $ref: '#/components/schemas/RegisterBeginRequest' required: true responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Passkey Register Begin Api V1 Passkeys Register Begin Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/passkeys/register/finish: post: tags: - responder - passkeys summary: Passkey Register Finish description: Verify the attestation response and persist the new credential. operationId: passkey_register_finish_api_v1_passkeys_register_finish_post requestBody: content: application/json: schema: $ref: '#/components/schemas/FinishRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/PasskeyCredentialOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/passkeys/authenticate/begin: post: tags: - responder - passkeys summary: Passkey Authenticate Begin description: 'Start a passkey-based login. If ``email`` is provided we constrain ``allowCredentials`` so only that user''s keys are tried. If omitted we go fully discoverable (the browser picks the right credential from its store).' operationId: passkey_authenticate_begin_api_v1_passkeys_authenticate_begin_post requestBody: content: application/json: schema: $ref: '#/components/schemas/AuthenticateBeginRequest' required: true responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Passkey Authenticate Begin Api V1 Passkeys Authenticate Begin Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/passkeys/authenticate/finish: post: tags: - responder - passkeys summary: Passkey Authenticate Finish description: Verify a passkey assertion and mint JWTs. operationId: passkey_authenticate_finish_api_v1_passkeys_authenticate_finish_post requestBody: content: application/json: schema: $ref: '#/components/schemas/FinishRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AuthenticateFinishResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/passkeys/credentials: get: tags: - responder - passkeys summary: List My Credentials description: List the current user's active passkeys. operationId: list_my_credentials_api_v1_passkeys_credentials_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/CredentialsListResponse' security: - HTTPBearer: [] /api/v1/passkeys/credentials/{credential_id}: delete: tags: - responder - passkeys summary: Revoke Credential description: Revoke (soft-delete) one of the current user's passkeys. operationId: revoke_credential_api_v1_passkeys_credentials__credential_id__delete security: - HTTPBearer: [] parameters: - name: credential_id in: path required: true schema: type: string format: uuid title: Credential Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/saved-views: get: tags: - saved-views summary: List Saved Views description: 'Return the caller''s saved views for one list page. Sorted by ``is_default DESC, updated_at DESC`` so the default preset always lands first, with the rest ordered by recency. The UI uses this ordering directly to render the saved-views menu.' operationId: list_saved_views_api_v1_saved_views_get security: - HTTPBearer: [] parameters: - name: view_type in: query required: true schema: type: string description: 'Which list page to return presets for. One of: alerts, cases, investigations, playbooks.' title: View Type description: 'Which list page to return presets for. One of: alerts, cases, investigations, playbooks.' responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/SavedViewModel' title: Response List Saved Views Api V1 Saved Views Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - saved-views summary: Create Saved View description: 'Create a new saved view. If ``is_default=True`` is passed, any existing default for the same ``(tenant, user, view_type)`` is demoted *first* so the partial unique index in 037 doesn''t trip. We do the demote + insert in a single transaction so a concurrent ``POST`` from the same user can''t leave the table without a default.' operationId: create_saved_view_api_v1_saved_views_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateSavedViewRequest' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/SavedViewModel' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/saved-views/{view_id}: patch: tags: - saved-views summary: Update Saved View description: 'Patch a saved view in place. Sending only ``is_default=True`` is the canonical "make this my default" path. We demote the existing default first inside the same transaction.' operationId: update_saved_view_api_v1_saved_views__view_id__patch security: - HTTPBearer: [] parameters: - name: view_id in: path required: true schema: type: string title: View Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateSavedViewRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/SavedViewModel' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - saved-views summary: Delete Saved View description: Delete a saved view owned by the caller. operationId: delete_saved_view_api_v1_saved_views__view_id__delete security: - HTTPBearer: [] parameters: - name: view_id in: path required: true schema: type: string title: View Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/assets: get: tags: - assets summary: List Assets operationId: list_assets_api_v1_assets_get security: - HTTPBearer: [] parameters: - name: asset_type in: query required: false schema: anyOf: - type: string - type: 'null' title: Asset Type - name: criticality in: query required: false schema: anyOf: - type: string - type: 'null' title: Criticality - name: limit in: query required: false schema: type: integer maximum: 500 default: 50 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/AssetOut' title: Response List Assets Api V1 Assets Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - assets summary: Create Asset operationId: create_asset_api_v1_assets_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AssetCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AssetOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/assets/{asset_id}: get: tags: - assets summary: Get Asset operationId: get_asset_api_v1_assets__asset_id__get security: - HTTPBearer: [] parameters: - name: asset_id in: path required: true schema: type: string format: uuid title: Asset Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AssetOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' patch: tags: - assets summary: Update Asset operationId: update_asset_api_v1_assets__asset_id__patch security: - HTTPBearer: [] parameters: - name: asset_id in: path required: true schema: type: string format: uuid title: Asset Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AssetUpdate' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AssetOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - assets summary: Delete Asset operationId: delete_asset_api_v1_assets__asset_id__delete security: - HTTPBearer: [] parameters: - name: asset_id in: path required: true schema: type: string format: uuid title: Asset Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/assets/vulnerabilities: get: tags: - assets summary: List Vulnerabilities operationId: list_vulnerabilities_api_v1_assets_vulnerabilities_get security: - HTTPBearer: [] parameters: - name: severity in: query required: false schema: anyOf: - type: string - type: 'null' title: Severity - name: is_exploited in: query required: false schema: anyOf: - type: boolean - type: 'null' title: Is Exploited - name: limit in: query required: false schema: type: integer maximum: 500 default: 50 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/VulnerabilityOut' title: Response List Vulnerabilities Api V1 Assets Vulnerabilities Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - assets summary: Create Vulnerability operationId: create_vulnerability_api_v1_assets_vulnerabilities_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/VulnerabilityCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/VulnerabilityOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/assets/{asset_id}/vulnerabilities: get: tags: - assets summary: List Asset Vulnerabilities operationId: list_asset_vulnerabilities_api_v1_assets__asset_id__vulnerabilities_get security: - HTTPBearer: [] parameters: - name: asset_id in: path required: true schema: type: string format: uuid title: Asset Id responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/VulnerabilityOut' title: Response List Asset Vulnerabilities Api V1 Assets Asset Id Vulnerabilities Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/mssp/children: get: tags: - mssp summary: List Child Tenants description: Return all child tenants of the current parent tenant. operationId: list_child_tenants_api_v1_mssp_children_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/ChildTenantOut' type: array title: Response List Child Tenants Api V1 Mssp Children Get security: - HTTPBearer: [] /api/v1/mssp/children/{child_id}/onboard: post: tags: - mssp summary: Onboard Child Tenant description: Link an existing tenant as a child of the current MSSP tenant. operationId: onboard_child_tenant_api_v1_mssp_children__child_id__onboard_post security: - HTTPBearer: [] parameters: - name: child_id in: path required: true schema: type: string format: uuid title: Child Id responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: type: string title: Response Onboard Child Tenant Api V1 Mssp Children Child Id Onboard Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/mssp/notes: get: tags: - mssp summary: List Notes operationId: list_notes_api_v1_mssp_notes_get security: - HTTPBearer: [] parameters: - name: child_id in: query required: false schema: anyOf: - type: string format: uuid - type: 'null' title: Child Id responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/TenantNoteOut' title: Response List Notes Api V1 Mssp Notes Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - mssp summary: Create Note operationId: create_note_api_v1_mssp_notes_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TenantNoteCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TenantNoteOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/mssp/delegations: get: tags: - mssp summary: List Delegations operationId: list_delegations_api_v1_mssp_delegations_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/DelegationOut' type: array title: Response List Delegations Api V1 Mssp Delegations Get security: - HTTPBearer: [] post: tags: - mssp summary: Create Delegation operationId: create_delegation_api_v1_mssp_delegations_post requestBody: content: application/json: schema: $ref: '#/components/schemas/DelegationCreate' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/DelegationOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/mssp/delegations/{delegation_id}: delete: tags: - mssp summary: Revoke Delegation operationId: revoke_delegation_api_v1_mssp_delegations__delegation_id__delete security: - HTTPBearer: [] parameters: - name: delegation_id in: path required: true schema: type: string format: uuid title: Delegation Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/mssp/metrics: get: tags: - mssp summary: List Metrics description: Return the latest metrics snapshot for every child tenant. operationId: list_metrics_api_v1_mssp_metrics_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/MetricsOut' type: array title: Response List Metrics Api V1 Mssp Metrics Get security: - HTTPBearer: [] /api/v1/mssp/rule-packs: get: tags: - mssp summary: List Rule Packs description: List all rule packs owned by the current parent tenant. operationId: list_rule_packs_api_v1_mssp_rule_packs_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/RulePackOut' type: array title: Response List Rule Packs Api V1 Mssp Rule Packs Get security: - HTTPBearer: [] post: tags: - mssp summary: Create Rule Pack description: Create a new rule pack (parent tenant only). operationId: create_rule_pack_api_v1_mssp_rule_packs_post requestBody: content: application/json: schema: $ref: '#/components/schemas/RulePackCreate' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RulePackOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/mssp/rule-packs/{pack_id}: get: tags: - mssp summary: Get Rule Pack operationId: get_rule_pack_api_v1_mssp_rule_packs__pack_id__get security: - HTTPBearer: [] parameters: - name: pack_id in: path required: true schema: type: string format: uuid title: Pack Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RulePackOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' put: tags: - mssp summary: Update Rule Pack operationId: update_rule_pack_api_v1_mssp_rule_packs__pack_id__put security: - HTTPBearer: [] parameters: - name: pack_id in: path required: true schema: type: string format: uuid title: Pack Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RulePackUpdate' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RulePackOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - mssp summary: Delete Rule Pack operationId: delete_rule_pack_api_v1_mssp_rule_packs__pack_id__delete security: - HTTPBearer: [] parameters: - name: pack_id in: path required: true schema: type: string format: uuid title: Pack Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/mssp/rule-packs/{pack_id}/rules: post: tags: - mssp summary: Add Rule To Pack operationId: add_rule_to_pack_api_v1_mssp_rule_packs__pack_id__rules_post security: - HTTPBearer: [] parameters: - name: pack_id in: path required: true schema: type: string format: uuid title: Pack Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RulePackRuleAdd' responses: '201': description: Successful Response content: application/json: schema: type: object additionalProperties: type: string title: Response Add Rule To Pack Api V1 Mssp Rule Packs Pack Id Rules Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/mssp/rule-packs/{pack_id}/rules/{rule_id}: delete: tags: - mssp summary: Remove Rule From Pack operationId: remove_rule_from_pack_api_v1_mssp_rule_packs__pack_id__rules__rule_id__delete security: - HTTPBearer: [] parameters: - name: pack_id in: path required: true schema: type: string format: uuid title: Pack Id - name: rule_id in: path required: true schema: type: string format: uuid title: Rule Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/mssp/rule-packs/{pack_id}/assign: post: tags: - mssp summary: Assign Pack To Child operationId: assign_pack_to_child_api_v1_mssp_rule_packs__pack_id__assign_post security: - HTTPBearer: [] parameters: - name: pack_id in: path required: true schema: type: string format: uuid title: Pack Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PackAssignmentCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/PackAssignmentOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/mssp/overrides: post: tags: - mssp summary: Create Rule Override operationId: create_rule_override_api_v1_mssp_overrides_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RuleOverrideCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RuleOverrideOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' get: tags: - mssp summary: List Overrides operationId: list_overrides_api_v1_mssp_overrides_get security: - HTTPBearer: [] parameters: - name: child_id in: query required: false schema: anyOf: - type: string format: uuid - type: 'null' title: Child Id responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/RuleOverrideOut' title: Response List Overrides Api V1 Mssp Overrides Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/mssp/overrides/{override_id}: delete: tags: - mssp summary: Delete Override operationId: delete_override_api_v1_mssp_overrides__override_id__delete security: - HTTPBearer: [] parameters: - name: override_id in: path required: true schema: type: string format: uuid title: Override Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/mssp/children/{child_id}/effective-rules: get: tags: - mssp summary: List Effective Rules For Child description: Preview the resolved rule set for a child tenant (parent-only). operationId: list_effective_rules_for_child_api_v1_mssp_children__child_id__effective_rules_get security: - HTTPBearer: [] parameters: - name: child_id in: path required: true schema: type: string format: uuid title: Child Id - name: category in: query required: false schema: anyOf: - type: string - type: 'null' title: Category - name: rule_language in: query required: false schema: anyOf: - type: string - type: 'null' title: Rule Language responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/EffectiveRuleOut' title: Response List Effective Rules For Child Api V1 Mssp Children Child Id Effective Rules Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/mssp/children/{child_id}/effective-rules/count: get: tags: - mssp summary: Count Effective Rules For Child description: Return source-breakdown counts for a child tenant's effective ruleset. operationId: count_effective_rules_for_child_api_v1_mssp_children__child_id__effective_rules_count_get security: - HTTPBearer: [] parameters: - name: child_id in: path required: true schema: type: string format: uuid title: Child Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/EffectiveRuleCountOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/mssp/overview: get: tags: - mssp summary: Mssp Overview description: Cross-tenant KPI summary for the MSSP parent dashboard. operationId: mssp_overview_api_v1_mssp_overview_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/MSSPKpiOverview' security: - HTTPBearer: [] /api/v1/mssp/tenants: get: tags: - mssp summary: List Managed Tenants description: List managed tenants with health scores for the parent dashboard. operationId: list_managed_tenants_api_v1_mssp_tenants_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/ManagedTenantRow' type: array title: Response List Managed Tenants Api V1 Mssp Tenants Get security: - HTTPBearer: [] /api/v1/mssp/incidents: get: tags: - mssp summary: List Cross Tenant Incidents description: Critical incidents across all managed tenants. operationId: list_cross_tenant_incidents_api_v1_mssp_incidents_get security: - HTTPBearer: [] parameters: - name: severity in: query required: false schema: anyOf: - type: string - type: 'null' description: 'Filter: high | medium | low' title: Severity description: 'Filter: high | medium | low' responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/CrossTenantIncident' title: Response List Cross Tenant Incidents Api V1 Mssp Incidents Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/insider-threat/profiles: get: tags: - insider-threat summary: List Profiles operationId: list_profiles_api_v1_insider_threat_profiles_get security: - HTTPBearer: [] parameters: - name: risk_tier in: query required: false schema: anyOf: - type: string - type: 'null' title: Risk Tier - name: watchlisted_only in: query required: false schema: type: boolean default: false title: Watchlisted Only - name: limit in: query required: false schema: type: integer maximum: 500 default: 50 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/RiskProfileOut' title: Response List Profiles Api V1 Insider Threat Profiles Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/insider-threat/profiles/{profile_id}: get: tags: - insider-threat summary: Get Profile operationId: get_profile_api_v1_insider_threat_profiles__profile_id__get security: - HTTPBearer: [] parameters: - name: profile_id in: path required: true schema: type: string format: uuid title: Profile Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RiskProfileOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/insider-threat/profiles/{profile_id}/watchlist: patch: tags: - insider-threat summary: Update Watchlist operationId: update_watchlist_api_v1_insider_threat_profiles__profile_id__watchlist_patch security: - HTTPBearer: [] parameters: - name: profile_id in: path required: true schema: type: string format: uuid title: Profile Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WatchlistUpdate' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RiskProfileOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/insider-threat/indicators: get: tags: - insider-threat summary: List Indicators operationId: list_indicators_api_v1_insider_threat_indicators_get security: - HTTPBearer: [] parameters: - name: severity in: query required: false schema: anyOf: - type: string - type: 'null' title: Severity - name: indicator_type in: query required: false schema: anyOf: - type: string - type: 'null' title: Indicator Type - name: limit in: query required: false schema: type: integer maximum: 500 default: 50 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/IndicatorOut' title: Response List Indicators Api V1 Insider Threat Indicators Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - insider-threat summary: Create Indicator operationId: create_indicator_api_v1_insider_threat_indicators_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/IndicatorCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/IndicatorOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/insider-threat/indicators/{indicator_id}/acknowledge: post: tags: - insider-threat summary: Acknowledge Indicator operationId: acknowledge_indicator_api_v1_insider_threat_indicators__indicator_id__acknowledge_post security: - HTTPBearer: [] parameters: - name: indicator_id in: path required: true schema: type: string format: uuid title: Indicator Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/IndicatorOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/insider-threat/peer-groups: get: tags: - insider-threat summary: List Peer Groups operationId: list_peer_groups_api_v1_insider_threat_peer_groups_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/PeerGroupOut' type: array title: Response List Peer Groups Api V1 Insider Threat Peer Groups Get security: - HTTPBearer: [] post: tags: - insider-threat summary: Create Peer Group operationId: create_peer_group_api_v1_insider_threat_peer_groups_post requestBody: content: application/json: schema: $ref: '#/components/schemas/PeerGroupCreate' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/PeerGroupOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/remediation/config: get: tags: - remediation summary: Get Maturity Config operationId: get_maturity_config_api_v1_remediation_config_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/MaturityOut' security: - HTTPBearer: [] put: tags: - remediation summary: Update Maturity Config operationId: update_maturity_config_api_v1_remediation_config_put requestBody: content: application/json: schema: $ref: '#/components/schemas/MaturityConfig' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/MaturityOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/remediation/gate-log: get: tags: - remediation summary: List Gate Log operationId: list_gate_log_api_v1_remediation_gate_log_get security: - HTTPBearer: [] parameters: - name: decision in: query required: false schema: anyOf: - type: string - type: 'null' title: Decision - name: limit in: query required: false schema: type: integer maximum: 500 default: 50 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/GateLogOut' title: Response List Gate Log Api V1 Remediation Gate Log Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/remediation/whitelist: get: tags: - remediation summary: List Whitelist operationId: list_whitelist_api_v1_remediation_whitelist_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/WhitelistOut' type: array title: Response List Whitelist Api V1 Remediation Whitelist Get security: - HTTPBearer: [] post: tags: - remediation summary: Add To Whitelist operationId: add_to_whitelist_api_v1_remediation_whitelist_post requestBody: content: application/json: schema: $ref: '#/components/schemas/WhitelistCreate' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/WhitelistOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/remediation/whitelist/{entry_id}: delete: tags: - remediation summary: Remove From Whitelist operationId: remove_from_whitelist_api_v1_remediation_whitelist__entry_id__delete security: - HTTPBearer: [] parameters: - name: entry_id in: path required: true schema: type: string format: uuid title: Entry Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/feedback/alert-override: post: tags: - feedback summary: Submit Alert Override description: 'Record an analyst verdict correction on an alert and surface retroactive re-disposition candidates.' operationId: submit_alert_override_api_v1_feedback_alert_override_post requestBody: content: application/json: schema: $ref: '#/components/schemas/AlertOverrideRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AlertOverrideResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/feedback/redisposition/apply: post: tags: - feedback summary: Apply Redisposition Endpoint description: Bulk-update the disposition on past alerts the analyst confirmed. operationId: apply_redisposition_endpoint_api_v1_feedback_redisposition_apply_post requestBody: content: application/json: schema: $ref: '#/components/schemas/RedispositionApplyRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RedispositionApplyResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/feedback/overrides: get: tags: - feedback summary: List Overrides Endpoint description: List analyst-override entries the agent has 'learned' from. operationId: list_overrides_endpoint_api_v1_feedback_overrides_get security: - HTTPBearer: [] parameters: - name: limit in: query required: false schema: type: integer default: 100 title: Limit responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/OverrideEntryModel' title: Response List Overrides Endpoint Api V1 Feedback Overrides Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/feedback/summary: get: tags: - feedback summary: Get Override Summary description: Return a summary of analyst overrides for this tenant. operationId: get_override_summary_api_v1_feedback_summary_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/OverrideSummaryResponse' security: - HTTPBearer: [] /api/v1/autonomy-policy: get: tags: - autonomy-policy summary: Get Autonomy Policy description: 'Return the effective autonomy policy for the calling tenant. For each known action we surface the merged thresholds (defaults + DB overrides), the hard-coded defaults, and an ``overridden`` flag the UI uses to render a "modified from default" badge.' operationId: get_autonomy_policy_api_v1_autonomy_policy_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AutonomyPolicyResponse' security: - HTTPBearer: [] /api/v1/autonomy-policy/{action}: put: tags: - autonomy-policy summary: Upsert Action Threshold description: 'Set (or update) the three-tier thresholds for one action. The new policy takes effect after the agent''s tenant-cache TTL expires or the cache is reset (``services/agents/app/policy/__init__.py`` ``reset_tenant_cache``).' operationId: upsert_action_threshold_api_v1_autonomy_policy__action__put security: - HTTPBearer: [] parameters: - name: action in: path required: true schema: type: string title: Action requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ThresholdUpdateRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ThresholdUpdateResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - autonomy-policy summary: Reset Action Threshold description: Reset a single action back to the hard-coded / YAML default. operationId: reset_action_threshold_api_v1_autonomy_policy__action__delete security: - HTTPBearer: [] parameters: - name: action in: path required: true schema: type: string title: Action responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/business-context/rules: get: tags: - business-context summary: Get Rules description: 'Return the tenant''s current rule set. Always returns a 200 — a tenant with no rules gets an empty list and an empty YAML body. The editor uses the ``enabled`` flag to show the "rules paused" banner so analysts aren''t surprised when a saved rule isn''t taking effect.' operationId: get_rules_api_v1_business_context_rules_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RulesEnvelope' security: - HTTPBearer: [] post: tags: - business-context summary: Replace Rules description: 'Replace the tenant''s whole rule set with a new YAML document. The engine snapshot is swapped atomically *before* the write "completes" from the caller''s perspective, so the next evaluation on the same process sees the fresh rules within microseconds — well inside the 1s "save → preview" budget the task spec calls out. Multi-process deployments still honour the budget because the JSONB-backed reload (T3.5-followup) will SET version on save and every worker re-pulls on TTL miss.' operationId: replace_rules_api_v1_business_context_rules_post requestBody: content: application/json: schema: $ref: '#/components/schemas/ReplaceRulesRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RulesEnvelope' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/business-context/rules/{rule_id}: put: tags: - business-context summary: Update Rule description: 'Patch a single rule by id. The body is the YAML for *that one rule*; we splice it into the tenant''s rule list, replacing the existing entry of the same id (or appending if it''s a new id). Returns the same envelope shape as ``POST /rules`` so the editor can re-render in one round trip.' operationId: update_rule_api_v1_business_context_rules__rule_id__put security: - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: string title: Rule Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/app__api__v1__endpoints__business_context__UpdateRuleRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RulesEnvelope' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - business-context summary: Delete Rule operationId: delete_rule_api_v1_business_context_rules__rule_id__delete security: - HTTPBearer: [] parameters: - name: rule_id in: path required: true schema: type: string title: Rule Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/business-context/rules/preview: post: tags: - business-context summary: Preview Rules description: 'Dry-run the candidate YAML against a sample of alerts. Doesn''t persist anything; doesn''t modify the engine snapshot for the tenant. The response is shaped so the settings page can render a before/after table with a one-line "X of Y alerts changed" header.' operationId: preview_rules_api_v1_business_context_rules_preview_post requestBody: content: application/json: schema: $ref: '#/components/schemas/PreviewRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/PreviewResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/nl-detection/translate: post: tags: - nl_detection summary: Translate Detection description: Convert a plain-English threat description into multi-platform detection rules. operationId: translate_detection_api_v1_nl_detection_translate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/NLDetectionRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/NLDetectionResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/detection-loop/suggest: post: tags: - detection_rules - detection_loop summary: Draft Sigma improvement for a FP alert description: 'Retrieve the triggering rule + alert evidence, then draft a Sigma improvement. Tenant isolation: the alert and rule lookups are scoped to ``user.tenant_id`` so a caller cannot pull another tenant''s evidence by guessing an ``alert_id``. ``TenantDBSession`` also sets the Postgres RLS context for defense in depth.' operationId: suggest_fp_fix_api_v1_detection_loop_suggest_post requestBody: content: application/json: schema: $ref: '#/components/schemas/SuggestRequest' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/SuggestionResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/detection-loop/suggestions: get: tags: - detection_rules - detection_loop summary: List LLM-drafted Sigma suggestions description: 'List suggestions drafted by *this* tenant only. Tenant isolation: ``_SUGGESTIONS`` is process-wide and shared across all tenants. Filtering on the stored ``tenant_id`` ensures one tenant never sees another tenant''s drafts, rule names, or evidence-derived rationale.' operationId: list_suggestions_api_v1_detection_loop_suggestions_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/SuggestionListResponse' security: - HTTPBearer: [] /api/v1/detection-loop/suggestions/{suggestion_id}: get: tags: - detection_rules - detection_loop summary: Get one Sigma suggestion description: 'Return one suggestion if and only if it belongs to the caller''s tenant. Tenant isolation: a cross-tenant lookup returns 404 (not 403) to avoid leaking the existence of a suggestion that belongs to another tenant.' operationId: get_suggestion_api_v1_detection_loop_suggestions__suggestion_id__get security: - HTTPBearer: [] parameters: - name: suggestion_id in: path required: true schema: type: string format: uuid title: Suggestion Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/SuggestionResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/nl-query/translate: post: tags: - nl_query summary: Translate a natural-language security question to ES|QL / SPL / KQL operationId: translate_query_api_v1_nl_query_translate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/NLQueryTranslateRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/NLQueryTranslateResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/nl-query/execute: post: tags: - nl_query summary: Translate NL question and execute ES|QL against Elasticsearch operationId: execute_query_api_v1_nl_query_execute_post requestBody: content: application/json: schema: $ref: '#/components/schemas/NLQueryExecuteRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/NLQueryExecuteResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/identity-timeline/build: post: tags: - identity_timeline summary: Build identity-centric investigation timeline operationId: build_timeline_api_v1_identity_timeline_build_post requestBody: content: application/json: schema: $ref: '#/components/schemas/BuildTimelineRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/IdentityTimeline' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/identity-timeline: get: tags: - identity_timeline summary: Quick timeline lookup for an identity operationId: get_timeline_api_v1_identity_timeline_get security: - HTTPBearer: [] parameters: - name: identity_kind in: query required: true schema: enum: - user - device - service_account - ip type: string title: Identity Kind - name: identity_value in: query required: true schema: type: string minLength: 1 title: Identity Value - name: hours in: query required: false schema: type: integer maximum: 8760 minimum: 1 default: 72 title: Hours responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/IdentityTimeline' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/translation/translate: post: tags: - translation summary: Translate a detection rule across formats operationId: translate_rule_api_v1_translation_translate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/TranslateRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TranslateResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/translation/formats: get: tags: - translation summary: List supported detection rule formats operationId: list_formats_api_v1_translation_formats_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FormatsResponse' /api/v1/hunts: get: tags: - hunts summary: List hunt hypotheses operationId: list_hunts_api_v1_hunts_get security: - HTTPBearer: [] parameters: - name: status in: query required: false schema: anyOf: - type: string - type: 'null' title: Status - name: priority in: query required: false schema: anyOf: - type: string - type: 'null' title: Priority - name: limit in: query required: false schema: type: integer maximum: 500 minimum: 1 default: 50 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/app__api__v1__endpoints__hunts__HuntResponse' title: Response List Hunts Api V1 Hunts Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - hunts summary: Create hunt hypothesis operationId: create_hunt_api_v1_hunts_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateHuntRequest' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/app__api__v1__endpoints__hunts__HuntResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/hunts/{hunt_id}: get: tags: - hunts summary: Get hunt operationId: get_hunt_api_v1_hunts__hunt_id__get security: - HTTPBearer: [] parameters: - name: hunt_id in: path required: true schema: type: string format: uuid title: Hunt Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/app__api__v1__endpoints__hunts__HuntResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' patch: tags: - hunts summary: Update hunt operationId: update_hunt_api_v1_hunts__hunt_id__patch security: - HTTPBearer: [] parameters: - name: hunt_id in: path required: true schema: type: string format: uuid title: Hunt Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateHuntRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/app__api__v1__endpoints__hunts__HuntResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/hunts/{hunt_id}/run: post: tags: - hunts summary: Execute hunt query operationId: run_hunt_api_v1_hunts__hunt_id__run_post security: - HTTPBearer: [] parameters: - name: hunt_id in: path required: true schema: type: string format: uuid title: Hunt Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/RunHuntRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/HuntRunResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/hunts/{hunt_id}/runs: get: tags: - hunts summary: List hunt runs operationId: list_runs_api_v1_hunts__hunt_id__runs_get security: - HTTPBearer: [] parameters: - name: hunt_id in: path required: true schema: type: string format: uuid title: Hunt Id responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/HuntRunResponse' title: Response List Runs Api V1 Hunts Hunt Id Runs Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/hunts/{hunt_id}/findings: post: tags: - hunts summary: Append findings operationId: add_findings_api_v1_hunts__hunt_id__findings_post security: - HTTPBearer: [] parameters: - name: hunt_id in: path required: true schema: type: string format: uuid title: Hunt Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AddFindingsRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/app__api__v1__endpoints__hunts__HuntResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/saved-hunts: get: tags: - saved-hunts summary: List Saved Hunts description: 'Return every saved hunt visible in the caller''s tenant. Sorted by ``updated_at DESC`` so the most recently re-run hunt lands first; the UI renders this list as the "Saved hunts" sidebar.' operationId: list_saved_hunts_api_v1_saved_hunts_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/SavedHuntModel' type: array title: Response List Saved Hunts Api V1 Saved Hunts Get security: - HTTPBearer: [] post: tags: - saved-hunts summary: Create Saved Hunt description: Translate the NL question and persist the hunt. operationId: create_saved_hunt_api_v1_saved_hunts_post requestBody: content: application/json: schema: $ref: '#/components/schemas/CreateSavedHuntRequest' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/SavedHuntModel' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/saved-hunts/{hunt_id}: get: tags: - saved-hunts summary: Get Saved Hunt description: Fetch one saved hunt. operationId: get_saved_hunt_api_v1_saved_hunts__hunt_id__get security: - HTTPBearer: [] parameters: - name: hunt_id in: path required: true schema: type: string title: Hunt Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/SavedHuntModel' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - saved-hunts summary: Delete Saved Hunt description: Delete a saved hunt owned by the caller's tenant. operationId: delete_saved_hunt_api_v1_saved_hunts__hunt_id__delete security: - HTTPBearer: [] parameters: - name: hunt_id in: path required: true schema: type: string title: Hunt Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/saved-hunts/{hunt_id}/run: post: tags: - saved-hunts summary: Run Saved Hunt description: 'Re-translate the saved NL question and stamp ``last_run_at``. Why re-translate on every run? The translator is the platform''s source of truth for "what does this question mean today?" — improving the translator (e.g. adding a new field alias) should automatically benefit saved hunts the next time they''re executed without an analyst having to re-save them. The stored ``translated_query`` is the snapshot taken at save time and serves as a baseline for diffing.' operationId: run_saved_hunt_api_v1_saved_hunts__hunt_id__run_post security: - HTTPBearer: [] parameters: - name: hunt_id in: path required: true schema: type: string title: Hunt Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RunSavedHuntResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/phishing/submit: post: tags: - phishing summary: Submit artifact for phishing triage operationId: submit_api_v1_phishing_submit_post requestBody: content: application/json: schema: $ref: '#/components/schemas/SubmitRequest' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/SubmissionResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/phishing/submissions: get: tags: - phishing summary: List phishing submissions operationId: list_submissions_api_v1_phishing_submissions_get security: - HTTPBearer: [] parameters: - name: verdict in: query required: false schema: anyOf: - type: string - type: 'null' title: Verdict - name: limit in: query required: false schema: type: integer maximum: 500 minimum: 1 default: 50 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/SubmissionResponse' title: Response List Submissions Api V1 Phishing Submissions Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/phishing/{submission_id}: get: tags: - phishing summary: Get submission operationId: get_submission_api_v1_phishing__submission_id__get security: - HTTPBearer: [] parameters: - name: submission_id in: path required: true schema: type: string format: uuid title: Submission Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/SubmissionResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/phishing/{submission_id}/retriage: post: tags: - phishing summary: Re-run triage on submission operationId: retriage_api_v1_phishing__submission_id__retriage_post security: - HTTPBearer: [] parameters: - name: submission_id in: path required: true schema: type: string format: uuid title: Submission Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/SubmissionResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/kb/ingest: post: tags: - knowledge_base summary: Ingest document into knowledge base operationId: ingest_api_v1_kb_ingest_post requestBody: content: application/json: schema: $ref: '#/components/schemas/IngestRequest' required: true responses: '201': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/KBDocResponse' type: array title: Response Ingest Api V1 Kb Ingest Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/kb/documents: get: tags: - knowledge_base summary: List KB documents operationId: list_documents_api_v1_kb_documents_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/KBDocResponse' type: array title: Response List Documents Api V1 Kb Documents Get security: - HTTPBearer: [] /api/v1/kb/documents/{doc_id}: get: tags: - knowledge_base summary: Get KB document operationId: get_document_api_v1_kb_documents__doc_id__get security: - HTTPBearer: [] parameters: - name: doc_id in: path required: true schema: type: string format: uuid title: Doc Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/KBDocResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - knowledge_base summary: Remove KB document operationId: delete_document_api_v1_kb_documents__doc_id__delete security: - HTTPBearer: [] parameters: - name: doc_id in: path required: true schema: type: string format: uuid title: Doc Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/kb/query: post: tags: - knowledge_base summary: Search knowledge base + optional LLM synthesis operationId: query_kb_api_v1_kb_query_post requestBody: content: application/json: schema: $ref: '#/components/schemas/QueryRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/QueryResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/threat-intel/iocs: get: tags: - threat-intel summary: List Iocs operationId: list_iocs_api_v1_threat_intel_iocs_get security: - HTTPBearer: [] parameters: - name: ioc_type in: query required: false schema: anyOf: - type: string - type: 'null' title: Ioc Type - name: severity in: query required: false schema: anyOf: - type: string - type: 'null' title: Severity - name: is_active in: query required: false schema: anyOf: - type: boolean - type: 'null' title: Is Active - name: limit in: query required: false schema: type: integer maximum: 500 default: 50 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/IOCOut' title: Response List Iocs Api V1 Threat Intel Iocs Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - threat-intel summary: Create Ioc operationId: create_ioc_api_v1_threat_intel_iocs_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/IOCCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/IOCOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/threat-intel/iocs/{ioc_id}: get: tags: - threat-intel summary: Get Ioc operationId: get_ioc_api_v1_threat_intel_iocs__ioc_id__get security: - HTTPBearer: [] parameters: - name: ioc_id in: path required: true schema: type: string format: uuid title: Ioc Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/IOCOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - threat-intel summary: Delete Ioc operationId: delete_ioc_api_v1_threat_intel_iocs__ioc_id__delete security: - HTTPBearer: [] parameters: - name: ioc_id in: path required: true schema: type: string format: uuid title: Ioc Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/threat-intel/actors: get: tags: - threat-intel summary: List Actors operationId: list_actors_api_v1_threat_intel_actors_get security: - HTTPBearer: [] parameters: - name: is_active in: query required: false schema: anyOf: - type: boolean - type: 'null' title: Is Active - name: limit in: query required: false schema: type: integer maximum: 200 default: 50 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/ThreatActorOut' title: Response List Actors Api V1 Threat Intel Actors Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - threat-intel summary: Create Actor operationId: create_actor_api_v1_threat_intel_actors_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ThreatActorCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ThreatActorOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/threat-intel/feeds: get: tags: - threat-intel summary: List Feeds operationId: list_feeds_api_v1_threat_intel_feeds_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/FeedOut' type: array title: Response List Feeds Api V1 Threat Intel Feeds Get security: - HTTPBearer: [] post: tags: - threat-intel summary: Create Feed operationId: create_feed_api_v1_threat_intel_feeds_post requestBody: content: application/json: schema: $ref: '#/components/schemas/FeedCreate' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FeedOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/threat-intel/feeds/{feed_id}: delete: tags: - threat-intel summary: Delete Feed operationId: delete_feed_api_v1_threat_intel_feeds__feed_id__delete security: - HTTPBearer: [] parameters: - name: feed_id in: path required: true schema: type: string format: uuid title: Feed Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/posture/findings: get: tags: - posture summary: List Findings operationId: list_findings_api_v1_posture_findings_get security: - HTTPBearer: [] parameters: - name: cloud_provider in: query required: false schema: anyOf: - type: string - type: 'null' title: Cloud Provider - name: severity in: query required: false schema: anyOf: - type: string - type: 'null' title: Severity - name: status in: query required: false schema: anyOf: - type: string - type: 'null' title: Status - name: rule_id in: query required: false schema: anyOf: - type: string - type: 'null' title: Rule Id - name: limit in: query required: false schema: type: integer maximum: 500 default: 50 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/FindingOut' title: Response List Findings Api V1 Posture Findings Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - posture summary: Ingest Finding operationId: ingest_finding_api_v1_posture_findings_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/FindingCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FindingOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/posture/findings/{finding_id}: get: tags: - posture summary: Get Finding operationId: get_finding_api_v1_posture_findings__finding_id__get security: - HTTPBearer: [] parameters: - name: finding_id in: path required: true schema: type: string format: uuid title: Finding Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FindingOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/posture/findings/{finding_id}/suppress: post: tags: - posture summary: Suppress Finding operationId: suppress_finding_api_v1_posture_findings__finding_id__suppress_post security: - HTTPBearer: [] parameters: - name: finding_id in: path required: true schema: type: string format: uuid title: Finding Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SuppressRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FindingOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/posture/findings/{finding_id}/resolve: post: tags: - posture summary: Resolve Finding operationId: resolve_finding_api_v1_posture_findings__finding_id__resolve_post security: - HTTPBearer: [] parameters: - name: finding_id in: path required: true schema: type: string format: uuid title: Finding Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/FindingOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/posture/summary: get: tags: - posture summary: Get Summary operationId: get_summary_api_v1_posture_summary_get security: - HTTPBearer: [] parameters: - name: cloud_provider in: query required: false schema: anyOf: - type: string - type: 'null' title: Cloud Provider responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/PostureSummary' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/posture/scans: get: tags: - posture summary: List Scans operationId: list_scans_api_v1_posture_scans_get security: - HTTPBearer: [] parameters: - name: limit in: query required: false schema: type: integer maximum: 100 default: 20 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/ScanRunOut' title: Response List Scans Api V1 Posture Scans Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/easm/scan: post: tags: - easm summary: Trigger Easm Scan description: 'Trigger an EASM discovery scan for a tenant (Tier 3.6). Runs passive connectors (Shodan / Censys) and, when enabled, an active TCP connect probe. Results are upserted into ``external_assets`` and drift events written to ``external_asset_drift``.' operationId: trigger_easm_scan_api_v1_easm_scan_post requestBody: content: application/json: schema: $ref: '#/components/schemas/ScanRequest' required: true responses: '202': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Trigger Easm Scan Api V1 Easm Scan Post '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/easm/assets: get: tags: - easm summary: List External Assets description: 'List externally discovered assets for a tenant. ``tenant_id`` defaults to the authenticated user''s tenant, so the analyst console can hit ``/easm/assets`` without explicit tenant scoping. A user can never request another tenant''s assets — supplying a foreign ``tenant_id`` returns 403.' operationId: list_external_assets_api_v1_easm_assets_get security: - HTTPBearer: [] parameters: - name: tenant_id in: query required: false schema: anyOf: - type: string format: uuid - type: 'null' title: Tenant Id - name: asset_type in: query required: false schema: anyOf: - $ref: '#/components/schemas/ExternalAssetType' - type: 'null' title: Asset Type - name: limit in: query required: false schema: type: integer maximum: 200 default: 50 title: Limit responses: '200': description: Successful Response content: application/json: schema: type: array items: type: object additionalProperties: true title: Response List External Assets Api V1 Easm Assets Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/easm/drift: get: tags: - easm summary: List External Asset Drift description: 'List drift events (new ports, certs, sub-domains, etc.). A user can never request another tenant''s drift events — supplying a foreign ``tenant_id`` returns 403.' operationId: list_external_asset_drift_api_v1_easm_drift_get security: - HTTPBearer: [] parameters: - name: tenant_id in: query required: false schema: anyOf: - type: string format: uuid - type: 'null' title: Tenant Id - name: external_asset_id in: query required: false schema: anyOf: - type: string format: uuid - type: 'null' title: External Asset Id - name: limit in: query required: false schema: type: integer maximum: 200 default: 50 title: Limit responses: '200': description: Successful Response content: application/json: schema: type: array items: type: object additionalProperties: true title: Response List External Asset Drift Api V1 Easm Drift Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/identity-graph/nodes: get: tags: - identity-graph summary: List Nodes operationId: list_nodes_api_v1_identity_graph_nodes_get security: - HTTPBearer: [] parameters: - name: node_type in: query required: false schema: anyOf: - type: string - type: 'null' title: Node Type - name: source_system in: query required: false schema: anyOf: - type: string - type: 'null' title: Source System - name: min_risk in: query required: false schema: anyOf: - type: number - type: 'null' title: Min Risk - name: limit in: query required: false schema: type: integer maximum: 500 default: 50 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/NodeOut' title: Response List Nodes Api V1 Identity Graph Nodes Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - identity-graph summary: Create Node operationId: create_node_api_v1_identity_graph_nodes_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/NodeCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/NodeOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/identity-graph/nodes/{node_id}: get: tags: - identity-graph summary: Get Node operationId: get_node_api_v1_identity_graph_nodes__node_id__get security: - HTTPBearer: [] parameters: - name: node_id in: path required: true schema: type: string format: uuid title: Node Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/NodeOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/identity-graph/nodes/{node_id}/edges: get: tags: - identity-graph summary: Get Node Edges operationId: get_node_edges_api_v1_identity_graph_nodes__node_id__edges_get security: - HTTPBearer: [] parameters: - name: node_id in: path required: true schema: type: string format: uuid title: Node Id responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/EdgeOut' title: Response Get Node Edges Api V1 Identity Graph Nodes Node Id Edges Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/identity-graph/edges: get: tags: - identity-graph summary: List Edges operationId: list_edges_api_v1_identity_graph_edges_get security: - HTTPBearer: [] parameters: - name: edge_type in: query required: false schema: anyOf: - type: string - type: 'null' title: Edge Type - name: limit in: query required: false schema: type: integer maximum: 1000 default: 100 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/EdgeOut' title: Response List Edges Api V1 Identity Graph Edges Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - identity-graph summary: Create Edge operationId: create_edge_api_v1_identity_graph_edges_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/EdgeCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/EdgeOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/identity-graph/alert-links: post: tags: - identity-graph summary: Link Alert To Identity operationId: link_alert_to_identity_api_v1_identity_graph_alert_links_post requestBody: content: application/json: schema: $ref: '#/components/schemas/AlertLinkCreate' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AlertLinkOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/identity-graph/alert-links/{alert_id}: get: tags: - identity-graph summary: Get Alert Identity Links operationId: get_alert_identity_links_api_v1_identity_graph_alert_links__alert_id__get security: - HTTPBearer: [] parameters: - name: alert_id in: path required: true schema: type: string format: uuid title: Alert Id responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/AlertLinkOut' title: Response Get Alert Identity Links Api V1 Identity Graph Alert Links Alert Id Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/reports/templates: get: tags: - reports summary: List Templates operationId: list_templates_api_v1_reports_templates_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/TemplateOut' type: array title: Response List Templates Api V1 Reports Templates Get security: - HTTPBearer: [] post: tags: - reports summary: Create Template operationId: create_template_api_v1_reports_templates_post requestBody: content: application/json: schema: $ref: '#/components/schemas/TemplateCreate' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TemplateOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/reports/templates/{template_id}: get: tags: - reports summary: Get Template operationId: get_template_api_v1_reports_templates__template_id__get security: - HTTPBearer: [] parameters: - name: template_id in: path required: true schema: type: string format: uuid title: Template Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TemplateOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' delete: tags: - reports summary: Delete Template operationId: delete_template_api_v1_reports_templates__template_id__delete security: - HTTPBearer: [] parameters: - name: template_id in: path required: true schema: type: string format: uuid title: Template Id responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/reports/artefacts: get: tags: - reports summary: List Artefacts operationId: list_artefacts_api_v1_reports_artefacts_get security: - HTTPBearer: [] parameters: - name: report_type in: query required: false schema: anyOf: - type: string - type: 'null' title: Report Type - name: status in: query required: false schema: anyOf: - type: string - type: 'null' title: Status - name: limit in: query required: false schema: type: integer maximum: 100 default: 20 title: Limit - name: offset in: query required: false schema: type: integer minimum: 0 default: 0 title: Offset responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/ArtefactOut' title: Response List Artefacts Api V1 Reports Artefacts Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/reports/generate: post: tags: - reports summary: Generate Report description: Enqueue a report generation job. Returns the artefact record immediately with status='pending'. operationId: generate_report_api_v1_reports_generate_post requestBody: content: application/json: schema: $ref: '#/components/schemas/GenerateRequest' required: true responses: '202': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ArtefactOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/reports/artefacts/{artefact_id}: get: tags: - reports summary: Get Artefact operationId: get_artefact_api_v1_reports_artefacts__artefact_id__get security: - HTTPBearer: [] parameters: - name: artefact_id in: path required: true schema: type: string format: uuid title: Artefact Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ArtefactOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/reports/digest/weekly: get: tags: - reports summary: Executive weekly digest (JSON, print-ready HTML, or PDF) description: "Build a deterministic weekly digest for the caller's tenant.\n\ \nSupported formats (``?format=``):\n\n* ``json`` — Pydantic model serialised\ \ as JSON *(default)*\n* ``html`` — Self-contained print-ready HTML page\n\ * ``pdf`` — Server-side PDF generated via WeasyPrint (requires the\n \ \ WeasyPrint native library stack; returns 503 when unavailable)" operationId: weekly_digest_api_v1_reports_digest_weekly_get security: - HTTPBearer: [] parameters: - name: format in: query required: false schema: type: string pattern: ^(json|html|pdf)$ default: json title: Format - name: period_start in: query required: false schema: anyOf: - type: string format: date-time - type: 'null' description: ISO timestamp; defaults to now-7d title: Period Start description: ISO timestamp; defaults to now-7d - name: period_end in: query required: false schema: anyOf: - type: string format: date-time - type: 'null' description: ISO timestamp; defaults to now title: Period End description: ISO timestamp; defaults to now responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/airgap/status: get: tags: - airgap summary: Current air-gap egress policy description: "Return the live air-gap policy snapshot for this pod.\n\nResponse\ \ shape::\n\n {\n \"enabled\": false,\n \"allowlist\": [\"\ mirror.example.com\"],\n \"implicit_private_suffixes\": [\".local\"\ , \".internal\", ...],\n \"policy\": \"Air-gapped mode is OFF — outbound\ \ HTTP is unrestricted.\"\n }\n\nThe ``policy`` field is a human-readable\ \ summary suitable for\nembedding in audit reports." operationId: get_airgap_status_api_v1_airgap_status_get responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Get Airgap Status Api V1 Airgap Status Get /api/v1/llm/status: get: tags: - llm summary: Current LLM provider configuration description: "Return the env-only LLM provider snapshot for this pod.\n\nIntentionally\ \ **unauthenticated** and **env-only**, mirroring\n``GET /api/v1/airgap/status``:\ \ the response carries no secrets\n(only ``key_set: bool``) and is safe for\ \ operator dashboards,\nauditors, and k8s liveness probes.\n\nTenant-aware\ \ callers (the web UI's \"Deployment & AI\" Settings\npanel, the agents service's\ \ explain path) layer per-tenant BYOK\noverrides on top of this baseline by\ \ either:\n\n* calling :func:`tenant_llm_status` with their own DB session,\ \ or\n* pairing this response with ``GET /api/v1/llm/credentials`` to\n perform\ \ the merge client-side." operationId: get_llm_status_api_v1_llm_status_get responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Get Llm Status Api V1 Llm Status Get /api/v1/llm/credentials: get: tags: - llm summary: Read the tenant's BYOK LLM credential description: 'Return the per-tenant LLM credential, or ``null`` if none stored. Returning ``null`` (rather than 404) on the empty case lets the UI render a single "Configure your LLM" CTA without dispatching on error codes. The Settings panel renders a "no credential set — falling back to platform defaults" hint when this is null.' operationId: get_llm_credential_api_v1_llm_credentials_get responses: '200': description: Successful Response content: application/json: schema: anyOf: - $ref: '#/components/schemas/LlmCredentialView' - type: 'null' title: Response Get Llm Credential Api V1 Llm Credentials Get security: - HTTPBearer: [] put: tags: - llm summary: Upsert the tenant's BYOK LLM credential description: "Create or update the tenant's BYOK credential.\n\nBehaviour notes:\n\ \n* ``api_key`` is required for hosted SaaS providers on first write.\n A\ \ subsequent PUT with ``api_key=null`` keeps the stored\n ciphertext (useful\ \ when toggling ``enabled`` or changing\n ``model`` without re-typing the\ \ secret).\n* Whenever ``api_key`` is provided we bump ``last_rotated_at``\ \ so\n the UI can render \"rotated 3 days ago\".\n* The audit row's ``changes``\ \ payload includes the *fact* of a\n rotation but never the key itself —\ \ we only record whether the\n key was changed, the previous + new providers,\ \ and whether the\n row is enabled." operationId: upsert_llm_credential_api_v1_llm_credentials_put requestBody: content: application/json: schema: $ref: '#/components/schemas/LlmCredentialUpsert' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/LlmCredentialView' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] delete: tags: - llm summary: Remove the tenant's BYOK LLM credential description: Hard-delete the credential. Platform falls back to env-var config. operationId: delete_llm_credential_api_v1_llm_credentials_delete responses: '204': description: Successful Response security: - HTTPBearer: [] /api/v1/threatintel/stix/indicators: get: tags: - Threat Intelligence summary: List Indicators description: List STIX 2.1 indicators from the threat intelligence store. operationId: list_indicators_api_v1_threatintel_stix_indicators_get parameters: - name: page in: query required: false schema: type: integer minimum: 1 default: 1 title: Page - name: page_size in: query required: false schema: type: integer maximum: 200 minimum: 1 default: 25 title: Page Size - name: label in: query required: false schema: anyOf: - type: string - type: 'null' title: Label responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/IndicatorListResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - Threat Intelligence summary: Create Indicator description: Publish a new STIX 2.1 indicator and optionally mirror it to MISP. operationId: create_indicator_api_v1_threatintel_stix_indicators_post parameters: - name: push_to_misp in: query required: false schema: anyOf: - type: boolean - type: 'null' description: Mirror this indicator to the configured MISP instance. Defaults to the value of MISP_PUSH_AUTO. title: Push To Misp description: Mirror this indicator to the configured MISP instance. Defaults to the value of MISP_PUSH_AUTO. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/STIXIndicatorCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/STIXIndicatorWithPush' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/threatintel/stix/bundles: get: tags: - Threat Intelligence summary: List Bundles description: List STIX 2.1 bundles. operationId: list_bundles_api_v1_threatintel_stix_bundles_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/BundleListResponse' post: tags: - Threat Intelligence summary: Create Bundle description: Create a new STIX 2.1 bundle and optionally mirror it to MISP. operationId: create_bundle_api_v1_threatintel_stix_bundles_post parameters: - name: push_to_misp in: query required: false schema: anyOf: - type: boolean - type: 'null' description: Mirror this bundle to the configured MISP instance as a single MISP event (one attribute per translatable indicator). Defaults to MISP_PUSH_AUTO. title: Push To Misp description: Mirror this bundle to the configured MISP instance as a single MISP event (one attribute per translatable indicator). Defaults to MISP_PUSH_AUTO. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/STIXBundleCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/STIXBundleWithPush' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/threatintel/stix/taxii/collections: get: tags: - Threat Intelligence summary: List Taxii Collections description: List TAXII 2.1 collections for server compatibility. operationId: list_taxii_collections_api_v1_threatintel_stix_taxii_collections_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TAXIICollectionListResponse' /api/v1/threatintel/stix/misp/health: get: tags: - Threat Intelligence - MISP push summary: Misp Push Health description: 'Check whether MISP push is configured and reachable. Surfaces enough state for an operator to debug a misconfigured deployment without leaking the API key. Calls ``/users/view/me`` against MISP only when the client is configured.' operationId: misp_push_health_api_v1_threatintel_stix_misp_health_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/MispPushHealth' /api/v1/threatintel/stix/misp/dry-run: post: tags: - Threat Intelligence - MISP push summary: Misp Push Dry Run description: 'Show the MISP event payload that *would* be pushed, without sending it. Useful for operators tuning STIX → MISP mappings, and for proving that an air-gapped deployment will refuse to send. The endpoint runs the air-gap check against the configured MISP URL and reports the result, but never opens an HTTP connection.' operationId: misp_push_dry_run_api_v1_threatintel_stix_misp_dry_run_post requestBody: content: application/json: schema: $ref: '#/components/schemas/MispDryRunRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/MispDryRunResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/shifts: get: tags: - shifts summary: List Shifts description: Return shift summaries, newest first. operationId: list_shifts_api_v1_shifts_get security: - HTTPBearer: [] parameters: - name: status in: query required: false schema: anyOf: - type: string - type: 'null' description: active | completed title: Status description: active | completed - name: limit in: query required: false schema: type: integer maximum: 100 minimum: 1 default: 20 title: Limit responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/ShiftSummary' title: Response List Shifts Api V1 Shifts Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - shifts summary: Create Shift description: Start a new shift. operationId: create_shift_api_v1_shifts_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ShiftCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ShiftSummary' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/shifts/current: get: tags: - shifts summary: Get Current Shift description: Return the currently active shift. operationId: get_current_shift_api_v1_shifts_current_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ShiftSummary' security: - HTTPBearer: [] /api/v1/shifts/{shift_id}/handoff: put: tags: - shifts summary: Add Handoff Notes description: Attach handoff notes to a shift and mark it completed. operationId: add_handoff_notes_api_v1_shifts__shift_id__handoff_put security: - HTTPBearer: [] parameters: - name: shift_id in: path required: true schema: type: string title: Shift Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/HandoffNotes' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/ShiftSummary' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/deployment/config: get: tags: - Deployment summary: Get Deployment Config description: Return the current deployment configuration. operationId: get_deployment_config_api_v1_deployment_config_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/DeploymentConfig' put: tags: - Deployment summary: Update Deployment Config description: Update deployment configuration fields. operationId: update_deployment_config_api_v1_deployment_config_put requestBody: content: application/json: schema: $ref: '#/components/schemas/DeploymentConfigUpdate' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/DeploymentConfig' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/deployment/airgap/status: get: tags: - Deployment summary: Get Airgap Status description: 'Check air-gap readiness: local LLM health, offline bundles, sync age.' operationId: get_airgap_status_api_v1_deployment_airgap_status_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AirgapStatus' /api/v1/deployment/airgap/bundle: post: tags: - Deployment summary: Create Airgap Bundle description: Trigger creation of an offline update bundle for air-gapped deployments. operationId: create_airgap_bundle_api_v1_deployment_airgap_bundle_post responses: '202': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/BundleJob' /api/v1/fusion/health: get: tags: - fusion summary: Fusion service health operationId: fusion_health_api_v1_fusion_health_get responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Fusion Health Api V1 Fusion Health Get /api/v1/fusion/metrics: get: tags: - fusion summary: Fusion worker metrics operationId: fusion_metrics_api_v1_fusion_metrics_get responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Fusion Metrics Api V1 Fusion Metrics Get /api/v1/fusion/ml/status: get: tags: - fusion summary: Fusion ML model status operationId: ml_status_api_v1_fusion_ml_status_get responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Ml Status Api V1 Fusion Ml Status Get /api/v1/fusion/entity-risk/queue: get: tags: - fusion summary: Top entities by risk score operationId: entity_risk_queue_api_v1_fusion_entity_risk_queue_get parameters: - name: tenant_id in: query required: true schema: type: string format: uuid title: Tenant Id - name: limit in: query required: false schema: type: integer maximum: 200 minimum: 1 default: 25 title: Limit - name: promoted_only in: query required: false schema: type: boolean default: false title: Promoted Only responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response Entity Risk Queue Api V1 Fusion Entity Risk Queue Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/fusion/entity-risk/stats: get: tags: - fusion summary: Entity-risk queue stats operationId: entity_risk_stats_api_v1_fusion_entity_risk_stats_get parameters: - name: tenant_id in: query required: true schema: type: string format: uuid title: Tenant Id responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response Entity Risk Stats Api V1 Fusion Entity Risk Stats Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/fusion/entity-risk/{entity_type}/{entity_value}: get: tags: - fusion summary: Entity risk record detail operationId: entity_risk_detail_api_v1_fusion_entity_risk__entity_type___entity_value__get parameters: - name: entity_type in: path required: true schema: type: string title: Entity Type - name: entity_value in: path required: true schema: type: string title: Entity Value - name: tenant_id in: query required: true schema: type: string format: uuid title: Tenant Id responses: '200': description: Successful Response content: application/json: schema: type: object additionalProperties: true title: Response Entity Risk Detail Api V1 Fusion Entity Risk Entity Type Entity Value Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/agents/tools: get: tags: - agents summary: List Agent Tools description: "Return the agent's allowed tool surface for this tenant.\n\nThe\ \ pivot is **instance × effective capability**:\n\n1. Pull every enabled connector\ \ for the tenant.\n2. For each instance, look up the connector class's declared\n\ \ capabilities from the live catalog.\n3. Intersect with the per-instance\ \ ``allowed_capabilities`` column\n (``NULL`` = no downscope; ``[]`` = explicit\ \ zero verbs; non-empty\n list = exact allowlist).\n4. Emit one ``AgentToolDescriptor``\ \ per surviving (instance, capability)\n pair.\n\nResult is sorted deterministically\ \ by ``(connector_name, capability)``\nso two consecutive calls return the\ \ same ordering — important for\nagent caches keyed off tool list hashes." operationId: list_agent_tools_api_v1_agents_tools_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AgentToolsResponse' security: - HTTPBearer: [] /api/v1/inbox/templates: get: tags: - inbox summary: List Templates description: List the vendor templates the operator can mint inbox URLs for. operationId: list_templates_api_v1_inbox_templates_get responses: '200': description: Successful Response content: application/json: schema: items: $ref: '#/components/schemas/InboxTemplateInfo' type: array title: Response List Templates Api V1 Inbox Templates Get security: - HTTPBearer: [] /api/v1/inbox/tokens: get: tags: - inbox summary: List Tokens description: 'List the calling tenant''s inbox tokens. By default revoked rows are filtered — operators rarely want to look at expired tokens, and showing them by default makes the "rotate token" flow noisy.' operationId: list_tokens_api_v1_inbox_tokens_get security: - HTTPBearer: [] parameters: - name: include_revoked in: query required: false schema: type: boolean default: false title: Include Revoked responses: '200': description: Successful Response content: application/json: schema: type: array items: $ref: '#/components/schemas/InboxTokenListItem' title: Response List Tokens Api V1 Inbox Tokens Get '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - inbox summary: Mint Token description: 'Mint a new inbox token for the calling tenant. Returns the plaintext token + absolute URL exactly once. Subsequent list/get calls return only the fingerprint.' operationId: mint_token_api_v1_inbox_tokens_post security: - HTTPBearer: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/InboxTokenCreate' responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/InboxTokenResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/inbox/tokens/{token_fingerprint}/rotate: post: tags: - inbox summary: Rotate Token description: 'Mint a new token with the same template/label/hmac, revoke the old. The wizard''s "rotate" button calls this when a URL leaks. Old token is marked revoked so the ingest service rejects requests for it immediately; new plaintext token is returned for the operator to paste into the vendor''s webhook config. We accept the fingerprint (not the full token) in the path so the plaintext token never appears in logs / proxy access logs.' operationId: rotate_token_api_v1_inbox_tokens__token_fingerprint__rotate_post security: - HTTPBearer: [] parameters: - name: token_fingerprint in: path required: true schema: type: string title: Token Fingerprint responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/InboxTokenResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/inbox/tokens/{token_fingerprint}: delete: tags: - inbox summary: Revoke Token description: 'Permanently revoke an inbox token without minting a replacement. The ingest service rejects revoked tokens; we keep the row so the UI can still show "this token was revoked at X" in audit views.' operationId: revoke_token_api_v1_inbox_tokens__token_fingerprint__delete security: - HTTPBearer: [] parameters: - name: token_fingerprint in: path required: true schema: type: string title: Token Fingerprint responses: '204': description: Successful Response '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/inbox/itsm/{tenant_token}/{connector_instance_id}: post: tags: - inbox-itsm summary: Inbound ITSM webhook (Jira / ServiceNow → AiSOC case) description: 'Receive a Jira / ServiceNow webhook and mirror status onto AiSOC. Public-facing — the only authenticator is the ``tenant_token`` in the URL (and an optional ``X-AiSOC-Signature`` HMAC). Rate limiting and DDoS protection are expected to live at the edge (Cloudflare / upstream LB), not here — the vendor''s source IPs are stable enough that the ops team can configure WAF rules. Always returns 200 (never 5xx) on the happy path, even when the payload doesn''t map to anything actionable. Vendor webhook implementations retry forever on non-2xx, and a stale ticket pinging a long-deleted case shouldn''t block the rest of the queue. We surface "nothing happened" via ``InboundResult.status_changed=False`` and a human-readable ``note``.' operationId: inbound_itsm_webhook_api_v1_inbox_itsm__tenant_token___connector_instance_id__post parameters: - name: tenant_token in: path required: true schema: type: string title: Tenant Token - name: connector_instance_id in: path required: true schema: type: string format: uuid title: Connector Instance Id - name: X-AiSOC-Signature in: header required: false schema: anyOf: - type: string - type: 'null' title: X-Aisoc-Signature responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/InboundResult' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/lake/sql: post: tags: - lake summary: Execute Lake Sql description: "Run a tenant-scoped SELECT against the warm tier.\n\nPipeline:\n\ \n1. Rate-limit the tenant.\n2. Rewrite the SQL — adds ``tenant_id`` predicates\ \ and clamps\n ``LIMIT``. Errors here are 400 (syntax) or 403 (forbidden).\n\ 3. Execute against ClickHouse with the configured timeout +\n resource caps.\ \ Errors here are 502 (driver/server error),\n 422 (timeout / memory limit),\ \ or 503 (driver not configured).\n4. Audit-log the call. We record the rewriter's\ \ view of the\n query (referenced tables, effective row cap) rather than\ \ the\n raw SQL, because audit logs are user-facing and we don't want\n\ \ to round-trip a malformed or PII-laden SQL string into the\n compliance\ \ UI." operationId: execute_lake_sql_api_v1_lake_sql_post requestBody: content: application/json: schema: $ref: '#/components/schemas/LakeQueryRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/LakeQueryResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/lake/schema: get: tags: - lake summary: Get Lake Schema description: 'Return column metadata for the lake''s allowlisted tables. Schema discovery is read-only and never returns row data, so it''s safe to grant to roles that should not be allowed to execute SELECTs (``viewer`` has ``lake:read_schema`` but not ``lake:query``). The response is also tenant-independent — everyone sees the same columns — but we still rate-limit and audit-log it so noisy clients can''t drum the endpoint into a DoS.' operationId: get_lake_schema_api_v1_lake_schema_get responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/LakeSchemaResponse' security: - HTTPBearer: [] /api/v1/waitlist/signup: post: tags: - waitlist summary: Public waitlist signup (rate-limited per IP). description: Persist a new signup, fire a Slack ping, return the entry id. operationId: signup_api_v1_waitlist_signup_post requestBody: content: application/json: schema: $ref: '#/components/schemas/WaitlistSignupRequest' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/WaitlistSignupResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/waitlist/entries: get: tags: - waitlist summary: List waitlist entries (admin only). operationId: list_entries_api_v1_waitlist_entries_get security: - HTTPBearer: [] parameters: - name: status_filter in: query required: false schema: anyOf: - type: string - type: 'null' title: Status Filter - name: limit in: query required: false schema: type: integer default: 100 title: Limit responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/WaitlistEntriesResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/waitlist/entries/{entry_id}: patch: tags: - waitlist summary: Update a waitlist entry's status (admin only). operationId: patch_entry_api_v1_waitlist_entries__entry_id__patch security: - HTTPBearer: [] parameters: - name: entry_id in: path required: true schema: type: string format: uuid title: Entry Id requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WaitlistPatchRequest' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/WaitlistEntryWire' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/admin/tenants/provision: post: tags: - admin - tenants summary: Promote a waitlist entry into a live managed tenant. description: 'Provision a new tenant from a waitlist entry. Idempotent on the waitlist entry id: a repeat call for an already-provisioned entry returns the existing tenant + a fresh invite link (the demo seed is *not* re-run). This keeps the support team from creating duplicate tenants if they click the button twice on a flaky network.' operationId: provision_tenant_api_v1_admin_tenants_provision_post requestBody: content: application/json: schema: $ref: '#/components/schemas/TenantProvisionRequest' required: true responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TenantProvisionResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - HTTPBearer: [] /api/v1/admin/tenants: get: tags: - admin - tenants summary: List tenants for the support team. description: Read-only tenant list, sorted by creation time descending. operationId: list_tenants_api_v1_admin_tenants_get security: - HTTPBearer: [] parameters: - name: q in: query required: false schema: anyOf: - type: string - type: 'null' title: Q - name: managed_only in: query required: false schema: type: boolean default: false title: Managed Only - name: limit in: query required: false schema: type: integer default: 200 title: Limit responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/TenantListResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/realtime/ticket: post: tags: - realtime summary: Mint Realtime Ticket description: 'Mint a short-lived ticket for the realtime WS/SSE edge. Requires a valid session (``get_current_user`` 401s otherwise). The ticket''s tenant is bound server-side from the authenticated user — the client cannot request a tenant.' operationId: mint_realtime_ticket_api_v1_realtime_ticket_post responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/RealtimeTicket' security: - HTTPBearer: [] /auth/saml/login: get: tags: - auth-saml summary: Saml Login description: Initiate SAML SSO — redirect to IdP. operationId: saml_login_auth_saml_login_get parameters: - name: redirect in: query required: false schema: type: string default: / title: Redirect responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /auth/saml/acs: post: tags: - auth-saml summary: Saml Acs description: Assertion Consumer Service — process IdP POST-back and issue JWT. operationId: saml_acs_auth_saml_acs_post responses: '200': description: Successful Response content: application/json: schema: {} /auth/saml/metadata: get: tags: - auth-saml summary: Saml Metadata description: Return SP SAML metadata XML. operationId: saml_metadata_auth_saml_metadata_get responses: '200': description: Successful Response content: application/json: schema: {} /auth/saml/logout: get: tags: - auth-saml summary: Saml Logout description: Initiate SAML SLO. operationId: saml_logout_auth_saml_logout_get responses: '200': description: Successful Response content: application/json: schema: {} /auth/oidc/login: get: tags: - auth-oidc summary: Oidc Login description: Initiate OIDC authorization code flow. operationId: oidc_login_auth_oidc_login_get parameters: - name: redirect in: query required: false schema: type: string default: / title: Redirect responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /auth/oidc/callback: get: tags: - auth-oidc summary: Oidc Callback description: Handle OIDC authorization code callback and issue JWT. operationId: oidc_callback_auth_oidc_callback_get parameters: - name: code in: query required: true schema: type: string title: Code - name: state in: query required: true schema: type: string title: State - name: error in: query required: false schema: anyOf: - type: string - type: 'null' title: Error responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /auth/oidc/userinfo: get: tags: - auth-oidc summary: Oidc Userinfo description: 'Proxy userinfo from upstream OIDC provider using the stored access token. Requires `Authorization: Bearer ` header — the JWT sub is used to look up the upstream token (stub: returns claims from AiSOC JWT).' operationId: oidc_userinfo_auth_oidc_userinfo_get responses: '200': description: Successful Response content: application/json: schema: {} /auth/oidc/logout: get: tags: - auth-oidc summary: Oidc Logout description: RP-initiated logout — clear cookie and redirect to provider end_session. operationId: oidc_logout_auth_oidc_logout_get parameters: - name: post_logout_redirect_uri in: query required: false schema: type: string default: / title: Post Logout Redirect Uri responses: '200': description: Successful Response content: application/json: schema: {} '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /graphql: get: tags: - graphql summary: Handle Http Get operationId: handle_http_get_graphql_get responses: '200': description: The GraphiQL integrated development environment. content: application/json: schema: {} '404': description: Not found if GraphiQL or query via GET are not enabled. security: - HTTPBearer: [] post: tags: - graphql summary: Handle Http Post operationId: handle_http_post_graphql_post responses: '200': description: Successful Response content: application/json: schema: {} security: - HTTPBearer: [] /health: get: tags: - system summary: Health Check description: 'Health check endpoint. Includes the current air-gap policy snapshot so operators can confirm zero-egress mode is engaged on this pod (Tier 3.1).' operationId: health_check_health_get responses: '200': description: Successful Response content: application/json: schema: additionalProperties: true type: object title: Response Health Check Health Get /metrics: get: tags: - system summary: Metrics description: "Prometheus metrics endpoint.\n\nAuth gate:\n\n* If ``settings.METRICS_TOKEN``\ \ is set, callers MUST present\n ``Authorization: Bearer ``.\ \ Comparison uses\n ``hmac.compare_digest`` to avoid timing leaks.\n* If\ \ ``METRICS_TOKEN`` is empty, the endpoint is open **only** in a\n development-class\ \ environment. In any other environment we refuse\n the scrape with a 401\ \ so operators don't accidentally ship an\n unauthenticated metrics endpoint\ \ to the open internet." operationId: metrics_metrics_get responses: '200': description: Successful Response content: application/json: schema: {} security: - HTTPBearer: [] components: schemas: ActionCount: properties: action: type: string title: Action count: type: integer title: Count type: object required: - action - count title: ActionCount description: How many of each kind of action SOC operators took. ActionPolicy: properties: action: type: string title: Action blast_radius: type: string title: Blast Radius thresholds: $ref: '#/components/schemas/ThresholdTriple' default_thresholds: $ref: '#/components/schemas/ThresholdTriple' overridden: type: boolean title: Overridden override_source: anyOf: - type: string - type: 'null' title: Override Source last_updated_at: anyOf: - type: string - type: 'null' title: Last Updated At last_updated_by: anyOf: - type: string - type: 'null' title: Last Updated By last_reason: anyOf: - type: string - type: 'null' title: Last Reason type: object required: - action - blast_radius - thresholds - default_thresholds - overridden title: ActionPolicy AddAlertsRequest: properties: alert_ids: items: type: string format: uuid type: array title: Alert Ids type: object required: - alert_ids title: AddAlertsRequest AddCommentRequest: properties: body: type: string minLength: 1 title: Body is_system: type: boolean title: Is System default: false type: object required: - body title: AddCommentRequest AddFindingsRequest: properties: findings: items: additionalProperties: true type: object type: array minItems: 1 title: Findings false_positive_rate: anyOf: - type: number maximum: 1.0 minimum: 0.0 - type: 'null' title: False Positive Rate type: object required: - findings title: AddFindingsRequest AdminInviteWire: properties: token: type: string title: Token expires_at: type: string title: Expires At url: type: string title: Url type: object required: - token - expires_at - url title: AdminInviteWire AgentToolDescriptor: properties: name: type: string title: Name description: Stable unique identifier for this tool, formatted as '.'. The connector_instance_id rather than connector_type so multiple instances of the same connector — e.g. two CrowdStrike tenants — are addressable. connector_id: type: string title: Connector Id description: Connector instance UUID. connector_type: type: string title: Connector Type description: Catalog connector type, e.g. 'crowdstrike'. connector_name: type: string title: Connector Name description: Operator-chosen instance display name (e.g. 'CrowdStrike — prod'). category: type: string title: Category description: Catalog category, e.g. 'edr', 'siem', 'iam'. capability: type: string title: Capability description: The capability verb (one of the values from the Capability enum, e.g. 'pull_alerts', 'query_logs', 'isolate_host'). capability_group: type: string title: Capability Group description: Coarse grouping derived from CAPABILITY_GROUPS in services/connectors. Lets an agent pre-filter by intent — e.g. only consider 'CONTAIN' verbs when deciding to quarantine a host. description: type: string title: Description description: Human-readable summary of the verb, surfaced in tool prompts. input_schema: additionalProperties: true type: object title: Input Schema description: JSON-Schema for the verb's arguments. Empty by default; concrete connectors will fill this in as the per-capability call surface stabilises in subsequent workstreams. type: object required: - name - connector_id - connector_type - connector_name - category - capability - capability_group - description title: AgentToolDescriptor description: "One callable verb on one connector instance, as the agent sees\ \ it.\n\nThe descriptor is intentionally LLM-friendly:\n\n* ``name`` is unique\ \ per tenant (``{connector_id}.{capability}``) and\n stable across redeploys,\ \ so an agent's tool-choice memory still\n resolves after a redeployment.\n\ * ``description`` is human-readable and pulled from the connector\n class\ \ so updates ship with the connector code, not the agent.\n* ``input_schema``\ \ follows JSON-Schema conventions so most agent\n frameworks (LangChain,\ \ LangGraph, MCP) can drop it in unchanged." AgentToolsResponse: properties: tools: items: $ref: '#/components/schemas/AgentToolDescriptor' type: array title: Tools tool_count: type: integer title: Tool Count connector_count: type: integer title: Connector Count type: object required: - tools - tool_count - connector_count title: AgentToolsResponse description: Tenant-wide tool catalogue surfaced to the agent layer. AirgapStatus: properties: ready: type: boolean title: Ready local_llm_status: type: string title: Local Llm Status local_llm_model: anyOf: - type: string - type: 'null' title: Local Llm Model offline_bundle_version: anyOf: - type: string - type: 'null' title: Offline Bundle Version last_sync: anyOf: - type: string - type: 'null' title: Last Sync detection_rules_count: type: integer title: Detection Rules Count threat_intel_age_hours: anyOf: - type: integer - type: 'null' title: Threat Intel Age Hours checks: items: additionalProperties: true type: object type: array title: Checks type: object required: - ready - local_llm_status - local_llm_model - offline_bundle_version - last_sync - detection_rules_count - threat_intel_age_hours - checks title: AirgapStatus AlertDetailResponse: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id title: type: string title: Title description: anyOf: - type: string - type: 'null' title: Description severity: type: string title: Severity status: type: string title: Status priority: type: integer title: Priority category: anyOf: - type: string - type: 'null' title: Category mitre_tactics: items: {} type: array title: Mitre Tactics mitre_techniques: items: {} type: array title: Mitre Techniques connector_type: anyOf: - type: string - type: 'null' title: Connector Type ai_score: anyOf: - type: number - type: 'null' title: Ai Score ai_summary: anyOf: - type: string - type: 'null' title: Ai Summary ai_recommendations: items: {} type: array title: Ai Recommendations confidence: anyOf: - type: integer - type: 'null' title: Confidence confidence_label: anyOf: - type: string - type: 'null' title: Confidence Label confidence_rationale: anyOf: - items: {} type: array - type: 'null' title: Confidence Rationale disposition: anyOf: - type: string - type: 'null' title: Disposition affected_ips: items: {} type: array title: Affected Ips affected_hosts: items: {} type: array title: Affected Hosts affected_users: items: {} type: array title: Affected Users case_id: anyOf: - type: string format: uuid - type: 'null' title: Case Id tags: items: {} type: array title: Tags event_time: type: string format: date-time title: Event Time first_seen: type: string format: date-time title: First Seen last_seen: type: string format: date-time title: Last Seen snoozed_until: anyOf: - type: string format: date-time - type: 'null' title: Snoozed Until snoozed_by_id: anyOf: - type: string format: uuid - type: 'null' title: Snoozed By Id created_at: type: string format: date-time title: Created At updated_at: type: string format: date-time title: Updated At narrative: anyOf: - type: string - type: 'null' title: Narrative related_entities: items: $ref: '#/components/schemas/RelatedEntity' type: array title: Related Entities default: [] mini_timeline: items: $ref: '#/components/schemas/MiniTimelineEvent' type: array title: Mini Timeline default: [] recommended_actions: items: $ref: '#/components/schemas/RecommendedAction' type: array title: Recommended Actions default: [] type: object required: - id - tenant_id - title - description - severity - status - priority - category - mitre_tactics - mitre_techniques - connector_type - ai_score - ai_summary - ai_recommendations - affected_ips - affected_hosts - affected_users - case_id - tags - event_time - first_seen - last_seen - created_at - updated_at title: AlertDetailResponse description: "Alert response enriched with everything the Investigation Rail\ \ needs.\n\nThe list endpoint stays on the smaller :class:`AlertResponse`\ \ shape\nto keep paginated payloads light. The detail endpoint promotes to\n\ this enriched shape so the rail renders without extra round-trips:\n\n* ``narrative``\ \ — deterministic correlation prose. Cached on the\n ``Alert`` row by the\ \ fusion service; lazily filled by the\n endpoint when missing (legacy rows).\ \ Always a string by the\n time it leaves the API.\n* ``related_entities``\ \ — pivotable entities grouped by\n principal / network / workflow / tenant.\n\ * ``mini_timeline`` — up to ``MAX_TIMELINE_EVENTS`` recent events\n merged\ \ from the case timeline and the audit log.\n* ``recommended_actions`` — normalised\ \ structured actions from\n the ResponderAgent (or the legacy list-of-strings\ \ shape)." AlertLinkCreate: properties: alert_id: type: string format: uuid title: Alert Id node_id: type: string format: uuid title: Node Id link_reason: type: string title: Link Reason confidence: type: number title: Confidence default: 1.0 type: object required: - alert_id - node_id - link_reason title: AlertLinkCreate AlertLinkOut: properties: alert_id: type: string format: uuid title: Alert Id node_id: type: string format: uuid title: Node Id link_reason: type: string title: Link Reason confidence: type: number title: Confidence default: 1.0 id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id created_at: type: string title: Created At type: object required: - alert_id - node_id - link_reason - id - tenant_id - created_at title: AlertLinkOut AlertListResponse: properties: items: items: $ref: '#/components/schemas/AlertResponse' type: array title: Items total: type: integer title: Total page: type: integer title: Page page_size: type: integer title: Page Size pages: type: integer title: Pages type: object required: - items - total - page - page_size - pages title: AlertListResponse AlertMetrics: properties: total: type: integer title: Total new: type: integer title: New critical: type: integer title: Critical high: type: integer title: High medium: type: integer title: Medium low: type: integer title: Low resolvedToday: type: integer title: Resolvedtoday mttr: type: number title: Mttr type: object required: - total - new - critical - high - medium - low - resolvedToday - mttr title: AlertMetrics AlertOverrideRequest: properties: alert_id: type: string title: Alert Id original_verdict: type: string title: Original Verdict description: The AI-generated verdict being overridden corrected_verdict: type: string title: Corrected Verdict description: 'Analyst''s verdict: true_positive | false_positive | benign | escalate' reason: anyOf: - type: string - type: 'null' title: Reason description: Optional free-text justification type: object required: - alert_id - original_verdict - corrected_verdict title: AlertOverrideRequest AlertOverrideResponse: properties: alert_id: type: string title: Alert Id corrected_verdict: type: string title: Corrected Verdict recorded_at: type: string title: Recorded At memory_key: anyOf: - type: string - type: 'null' title: Memory Key redisposition_candidates: items: $ref: '#/components/schemas/RedispositionCandidateModel' type: array title: Redisposition Candidates type: object required: - alert_id - corrected_verdict - recorded_at title: AlertOverrideResponse AlertResponse: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id title: type: string title: Title description: anyOf: - type: string - type: 'null' title: Description severity: type: string title: Severity status: type: string title: Status priority: type: integer title: Priority category: anyOf: - type: string - type: 'null' title: Category mitre_tactics: items: {} type: array title: Mitre Tactics mitre_techniques: items: {} type: array title: Mitre Techniques connector_type: anyOf: - type: string - type: 'null' title: Connector Type ai_score: anyOf: - type: number - type: 'null' title: Ai Score ai_summary: anyOf: - type: string - type: 'null' title: Ai Summary ai_recommendations: items: {} type: array title: Ai Recommendations confidence: anyOf: - type: integer - type: 'null' title: Confidence confidence_label: anyOf: - type: string - type: 'null' title: Confidence Label confidence_rationale: anyOf: - items: {} type: array - type: 'null' title: Confidence Rationale disposition: anyOf: - type: string - type: 'null' title: Disposition affected_ips: items: {} type: array title: Affected Ips affected_hosts: items: {} type: array title: Affected Hosts affected_users: items: {} type: array title: Affected Users case_id: anyOf: - type: string format: uuid - type: 'null' title: Case Id tags: items: {} type: array title: Tags event_time: type: string format: date-time title: Event Time first_seen: type: string format: date-time title: First Seen last_seen: type: string format: date-time title: Last Seen snoozed_until: anyOf: - type: string format: date-time - type: 'null' title: Snoozed Until snoozed_by_id: anyOf: - type: string format: uuid - type: 'null' title: Snoozed By Id created_at: type: string format: date-time title: Created At updated_at: type: string format: date-time title: Updated At type: object required: - id - tenant_id - title - description - severity - status - priority - category - mitre_tactics - mitre_techniques - connector_type - ai_score - ai_summary - ai_recommendations - affected_ips - affected_hosts - affected_users - case_id - tags - event_time - first_seen - last_seen - created_at - updated_at title: AlertResponse AlertSnoozeRequest: properties: duration_minutes: anyOf: - type: integer - type: 'null' title: Duration Minutes until: anyOf: - type: string format: date-time - type: 'null' title: Until reason: anyOf: - type: string - type: 'null' title: Reason type: object title: AlertSnoozeRequest description: Snooze an alert from the mobile responder PWA. AlertStatsResponse: properties: total: type: integer title: Total by_severity: additionalProperties: type: integer type: object title: By Severity by_status: additionalProperties: type: integer type: object title: By Status new_last_24h: type: integer title: New Last 24H critical_open: type: integer title: Critical Open type: object required: - total - by_severity - by_status - new_last_24h - critical_open title: AlertStatsResponse AlertSubmitRequest: properties: events: items: additionalProperties: true type: object type: array title: Events default: [] connector_id: anyOf: - type: string - type: 'null' title: Connector Id connector_type: anyOf: - type: string - type: 'null' title: Connector Type source_format: anyOf: - type: string - type: 'null' title: Source Format title: anyOf: - type: string - type: 'null' title: Title description: anyOf: - type: string - type: 'null' title: Description severity: anyOf: - type: string - type: 'null' title: Severity tags: anyOf: - items: type: string type: array - type: 'null' title: Tags type: object title: AlertSubmitRequest description: "Direct-write alert submission payload.\n\nThe founder-flow demo\ \ (`aisoc submit `) and any operator who wants\nto land a hand-crafted\ \ alert on the local dev stack without a connector\nPOST one of these. The\ \ body intentionally mirrors the ingest envelope\nused by real connectors\ \ so the same fixture works against either path:\n\n { connector_id, connector_type,\ \ source_format, events: [...] }\n\nThe single payload synthesises one ``Alert``\ \ row, written directly into\nthe tenant's database, so the result is visible\ \ in\n``GET /api/v1/alerts`` and the web console within the same second.\n\ This deliberately bypasses the Kafka detection/correlation pipeline\n(which\ \ fresh clones don't run by default) so the documented \"alert in\nseconds\"\ \ promise in the quickstart actually holds." AlertUpdateRequest: properties: status: anyOf: - type: string - type: 'null' title: Status priority: anyOf: - type: integer - type: 'null' title: Priority tags: anyOf: - items: type: string type: array - type: 'null' title: Tags assigned_to_id: anyOf: - type: string format: uuid - type: 'null' title: Assigned To Id case_id: anyOf: - type: string format: uuid - type: 'null' title: Case Id type: object title: AlertUpdateRequest ApiKeyOut: properties: id: type: string format: uuid title: Id name: type: string title: Name prefix: type: string title: Prefix scopes: items: type: string type: array title: Scopes is_active: type: boolean title: Is Active expires_at: anyOf: - type: string format: date-time - type: 'null' title: Expires At last_used_at: anyOf: - type: string format: date-time - type: 'null' title: Last Used At created_at: type: string format: date-time title: Created At type: object required: - id - name - prefix - scopes - is_active - expires_at - last_used_at - created_at title: ApiKeyOut ApplyTuningRequest: properties: action: type: string enum: - raise_threshold - add_suppression - disable - acknowledge title: Action note: anyOf: - type: string - type: 'null' title: Note threshold: anyOf: - type: integer maximum: 1000000.0 minimum: 1.0 - type: 'null' title: Threshold description: Override threshold to set when action='raise_threshold'. suppression_reason: anyOf: - type: string maxLength: 255 - type: 'null' title: Suppression Reason description: Free-text reason recorded with the suppression placeholder. type: object required: - action title: ApplyTuningRequest description: Body for ``POST /detection/tuning/{rule_id}/apply``. ApprovalCreateRequest: properties: run_id: anyOf: - type: string format: uuid - type: 'null' title: Run Id case_id: anyOf: - type: string maxLength: 200 - type: 'null' title: Case Id alert_id: anyOf: - type: string format: uuid - type: 'null' title: Alert Id requested_by: type: string maxLength: 120 title: Requested By default: agent required_user_id: anyOf: - type: string format: uuid - type: 'null' title: Required User Id required_topic: anyOf: - type: string maxLength: 80 - type: 'null' title: Required Topic title: type: string maxLength: 200 minLength: 1 title: Title summary: type: string minLength: 1 title: Summary risk_level: type: string enum: - low - medium - high - critical title: Risk Level default: medium action: additionalProperties: true type: object title: Action expires_at: anyOf: - type: string format: date-time - type: 'null' title: Expires At type: object required: - title - summary title: ApprovalCreateRequest ApprovalDecisionRequest: properties: decision: type: string enum: - approve - deny title: Decision comment: anyOf: - type: string maxLength: 2000 - type: 'null' title: Comment type: object required: - decision title: ApprovalDecisionRequest ApprovalListResponse: properties: items: items: $ref: '#/components/schemas/ApprovalResponse' type: array title: Items total: type: integer title: Total page: type: integer title: Page page_size: type: integer title: Page Size pages: type: integer title: Pages type: object required: - items - total - page - page_size - pages title: ApprovalListResponse ApprovalResponse: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id run_id: anyOf: - type: string format: uuid - type: 'null' title: Run Id case_id: anyOf: - type: string - type: 'null' title: Case Id alert_id: anyOf: - type: string format: uuid - type: 'null' title: Alert Id requested_by: type: string title: Requested By required_user_id: anyOf: - type: string format: uuid - type: 'null' title: Required User Id required_topic: anyOf: - type: string - type: 'null' title: Required Topic title: type: string title: Title summary: type: string title: Summary risk_level: type: string title: Risk Level action: additionalProperties: true type: object title: Action status: type: string title: Status decided_by_id: anyOf: - type: string format: uuid - type: 'null' title: Decided By Id decided_at: anyOf: - type: string format: date-time - type: 'null' title: Decided At decision_comment: anyOf: - type: string - type: 'null' title: Decision Comment expires_at: anyOf: - type: string format: date-time - type: 'null' title: Expires At created_at: type: string format: date-time title: Created At updated_at: type: string format: date-time title: Updated At type: object required: - id - tenant_id - run_id - case_id - alert_id - requested_by - required_user_id - required_topic - title - summary - risk_level - action - status - decided_by_id - decided_at - decision_comment - expires_at - created_at - updated_at title: ApprovalResponse ArtefactOut: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id template_id: anyOf: - type: string format: uuid - type: 'null' title: Template Id report_type: type: string title: Report Type title: type: string title: Title period_start: type: string title: Period Start period_end: type: string title: Period End output_format: type: string title: Output Format file_size_bytes: anyOf: - type: integer - type: 'null' title: File Size Bytes delivered_to: anyOf: - items: type: string type: array - type: 'null' title: Delivered To delivered_at: anyOf: - type: string - type: 'null' title: Delivered At generated_by: type: string title: Generated By status: type: string title: Status error_message: anyOf: - type: string - type: 'null' title: Error Message created_at: type: string title: Created At type: object required: - id - tenant_id - template_id - report_type - title - period_start - period_end - output_format - file_size_bytes - delivered_to - delivered_at - generated_by - status - error_message - created_at title: ArtefactOut ArtifactDetail: properties: id: type: string format: uuid title: Id kind: type: string title: Kind sha256: type: string title: Sha256 size_bytes: type: integer title: Size Bytes event_id: anyOf: - type: string format: uuid - type: 'null' title: Event Id created_at: type: string format: date-time title: Created At content: anyOf: - type: string - type: 'null' title: Content blob_ref: anyOf: - type: string - type: 'null' title: Blob Ref type: object required: - id - kind - sha256 - size_bytes - event_id - created_at - content - blob_ref title: ArtifactDetail ArtifactSummary: properties: id: type: string format: uuid title: Id kind: type: string title: Kind sha256: type: string title: Sha256 size_bytes: type: integer title: Size Bytes event_id: anyOf: - type: string format: uuid - type: 'null' title: Event Id created_at: type: string format: date-time title: Created At type: object required: - id - kind - sha256 - size_bytes - event_id - created_at title: ArtifactSummary AssetCreate: properties: asset_type: type: string title: Asset Type default: host name: type: string title: Name fqdn: anyOf: - type: string - type: 'null' title: Fqdn ip_addresses: anyOf: - items: type: string type: array - type: 'null' title: Ip Addresses cloud_provider: anyOf: - type: string - type: 'null' title: Cloud Provider cloud_region: anyOf: - type: string - type: 'null' title: Cloud Region cloud_account: anyOf: - type: string - type: 'null' title: Cloud Account os: anyOf: - type: string - type: 'null' title: Os os_version: anyOf: - type: string - type: 'null' title: Os Version criticality: type: string title: Criticality default: medium tags: anyOf: - items: type: string type: array - type: 'null' title: Tags owner_email: anyOf: - type: string - type: 'null' title: Owner Email metadata: additionalProperties: true type: object title: Metadata type: object required: - name title: AssetCreate AssetOut: properties: asset_type: type: string title: Asset Type default: host name: type: string title: Name fqdn: anyOf: - type: string - type: 'null' title: Fqdn ip_addresses: anyOf: - items: type: string type: array - type: 'null' title: Ip Addresses cloud_provider: anyOf: - type: string - type: 'null' title: Cloud Provider cloud_region: anyOf: - type: string - type: 'null' title: Cloud Region cloud_account: anyOf: - type: string - type: 'null' title: Cloud Account os: anyOf: - type: string - type: 'null' title: Os os_version: anyOf: - type: string - type: 'null' title: Os Version criticality: type: string title: Criticality default: medium tags: anyOf: - items: type: string type: array - type: 'null' title: Tags owner_email: anyOf: - type: string - type: 'null' title: Owner Email metadata: additionalProperties: true type: object title: Metadata id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id created_at: type: string title: Created At updated_at: type: string title: Updated At last_seen: type: string title: Last Seen first_seen: type: string title: First Seen asset_metadata: additionalProperties: true type: object title: Asset Metadata type: object required: - name - id - tenant_id - created_at - updated_at - last_seen - first_seen title: AssetOut AssetUpdate: properties: asset_type: type: string title: Asset Type default: host name: type: string title: Name fqdn: anyOf: - type: string - type: 'null' title: Fqdn ip_addresses: anyOf: - items: type: string type: array - type: 'null' title: Ip Addresses cloud_provider: anyOf: - type: string - type: 'null' title: Cloud Provider cloud_region: anyOf: - type: string - type: 'null' title: Cloud Region cloud_account: anyOf: - type: string - type: 'null' title: Cloud Account os: anyOf: - type: string - type: 'null' title: Os os_version: anyOf: - type: string - type: 'null' title: Os Version criticality: type: string title: Criticality default: medium tags: anyOf: - items: type: string type: array - type: 'null' title: Tags owner_email: anyOf: - type: string - type: 'null' title: Owner Email metadata: additionalProperties: true type: object title: Metadata type: object required: - name title: AssetUpdate AttackHeatmapCell: properties: tactic: type: string title: Tactic technique: type: string title: Technique count: type: integer title: Count type: object required: - tactic - technique - count title: AttackHeatmapCell AttackPathResponse: properties: case_id: type: string title: Case Id nodes: items: $ref: '#/components/schemas/GraphNode' type: array title: Nodes edges: items: $ref: '#/components/schemas/GraphEdge' type: array title: Edges node_count: type: integer title: Node Count edge_count: type: integer title: Edge Count type: object required: - case_id - nodes - edges - node_count - edge_count title: AttackPathResponse AuditEventOut: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id actor_id: anyOf: - type: string format: uuid - type: 'null' title: Actor Id actor_email: anyOf: - type: string - type: 'null' title: Actor Email actor_ip: anyOf: - type: string - type: 'null' title: Actor Ip action: type: string title: Action resource: anyOf: - type: string - type: 'null' title: Resource resource_id: anyOf: - type: string - type: 'null' title: Resource Id changes: anyOf: - additionalProperties: true type: object - type: 'null' title: Changes created_at: type: string title: Created At type: object required: - id - tenant_id - actor_id - actor_email - actor_ip - action - resource - resource_id - changes - created_at title: AuditEventOut AuditListResponse: properties: items: items: $ref: '#/components/schemas/AuditEventOut' type: array title: Items total: type: integer title: Total page: type: integer title: Page page_size: type: integer title: Page Size total_pages: type: integer title: Total Pages type: object required: - items - total - page - page_size - total_pages title: AuditListResponse AuthenticateBeginRequest: properties: email: anyOf: - type: string format: email - type: 'null' title: Email type: object title: AuthenticateBeginRequest AuthenticateFinishResponse: properties: access_token: type: string title: Access Token refresh_token: type: string title: Refresh Token token_type: type: string title: Token Type default: bearer expires_in: type: integer title: Expires In default: 1800 type: object required: - access_token - refresh_token title: AuthenticateFinishResponse AutoTuneRequest: properties: enabled: type: boolean title: Enabled type: object required: - enabled title: AutoTuneRequest description: Body for ``POST /detection/tuning/{rule_id}/auto_tune``. AutonomyPolicyResponse: properties: tenant_id: type: string title: Tenant Id actions: items: $ref: '#/components/schemas/ActionPolicy' type: array title: Actions type: object required: - tenant_id - actions title: AutonomyPolicyResponse BaselineResponse: properties: id: type: string format: uuid title: Id tenant_id: anyOf: - type: string format: uuid - type: 'null' title: Tenant Id suite: type: string title: Suite score: type: number title: Score payload: additionalProperties: true type: object title: Payload is_active: type: boolean title: Is Active recorded_by_id: anyOf: - type: string format: uuid - type: 'null' title: Recorded By Id created_at: type: string format: date-time title: Created At type: object required: - id - tenant_id - suite - score - payload - is_active - recorded_by_id - created_at title: BaselineResponse BlastRadiusResponse: properties: entity_id: type: string title: Entity Id entity_type: type: string title: Entity Type hops: type: integer title: Hops affected_nodes: items: $ref: '#/components/schemas/GraphNode' type: array title: Affected Nodes total_affected: type: integer title: Total Affected type_breakdown: additionalProperties: type: integer type: object title: Type Breakdown blast_radius_score: type: number title: Blast Radius Score type: object required: - entity_id - entity_type - hops - affected_nodes - total_affected - type_breakdown - blast_radius_score title: BlastRadiusResponse BuildTimelineRequest: properties: identity_kind: type: string enum: - user - device - service_account - ip title: Identity Kind description: Type of identity anchor. identity_value: type: string minLength: 1 title: Identity Value description: Identity value (e.g. username, hostname). from_ts: anyOf: - type: string format: date-time - type: 'null' title: From Ts description: Start of window (defaults to 72 h ago). to_ts: anyOf: - type: string format: date-time - type: 'null' title: To Ts description: End of window (defaults to now). max_events: type: integer maximum: 2000.0 minimum: 1.0 title: Max Events default: 200 type: object required: - identity_kind - identity_value title: BuildTimelineRequest BulkToggleBody: properties: ruleIds: items: type: string type: array minItems: 1 title: Ruleids enabled: type: boolean title: Enabled type: object required: - enabled title: BulkToggleBody description: 'Bulk enable/disable payload from the analyst console. ``ruleIds`` are accepted as plain strings so the frontend can pass the same IDs it already renders from ``GET /rules`` without parsing UUIDs.' BulkToggleResponse: properties: updated: type: integer title: Updated skipped: items: type: string type: array title: Skipped type: object required: - updated - skipped title: BulkToggleResponse BundleJob: properties: job_id: type: string title: Job Id status: type: string title: Status created_at: type: string title: Created At estimated_size_mb: type: integer title: Estimated Size Mb includes: items: type: string type: array title: Includes type: object required: - job_id - status - created_at - estimated_size_mb - includes title: BundleJob BundleListResponse: properties: items: items: $ref: '#/components/schemas/STIXBundle' type: array title: Items total: type: integer title: Total type: object required: - items - total title: BundleListResponse ByokSavings: properties: is_byok_active: type: boolean title: Is Byok Active provider: type: string title: Provider recorded_cost_usd: type: number title: Recorded Cost Usd imputed_public_cost_usd: type: number title: Imputed Public Cost Usd savings_usd: type: number title: Savings Usd type: object required: - is_byok_active - provider - recorded_cost_usd - imputed_public_cost_usd - savings_usd title: ByokSavings description: 'Imputed savings vs hosted pricing. ``is_byok_active`` is True when the live LLM provider (per ``/llm/status``) is loopback or private — i.e. the operator is actually running their own model. When False, the savings are still computed (so the UI can show "if you switched to BYOK, you''d save ~X") but should be labelled "potential savings" in the UI.' CalibrationBucket: properties: predicted_lower: type: number title: Predicted Lower predicted_upper: type: number title: Predicted Upper sample_count: type: integer title: Sample Count actual_tp_rate: type: number title: Actual Tp Rate type: object required: - predicted_lower - predicted_upper - sample_count - actual_tp_rate title: CalibrationBucket description: 'One bucket of the agent confidence reliability curve. `predicted_lower` and `predicted_upper` define the AI-confidence range (e.g., 0.8–1.0). `actual_tp_rate` is the observed true-positive rate among analyst-dispositioned alerts whose ai_score landed in that bucket — i.e., the empirical hit-rate the model claimed.' CaseMetrics: properties: open: type: integer title: Open inProgress: type: integer title: Inprogress resolvedThisWeek: type: integer title: Resolvedthisweek type: object required: - open - inProgress - resolvedThisWeek title: CaseMetrics CaseResponse: properties: id: type: string format: uuid title: Id case_number: anyOf: - type: string - type: 'null' title: Case Number title: type: string title: Title description: anyOf: - type: string - type: 'null' title: Description severity: type: string title: Severity status: type: string title: Status assignee: anyOf: - type: string - type: 'null' title: Assignee mitre_techniques: items: type: string type: array title: Mitre Techniques alert_ids: items: type: string format: uuid type: array title: Alert Ids observable_graph: additionalProperties: true type: object title: Observable Graph evidence_chain: items: additionalProperties: true type: object type: array title: Evidence Chain compliance_frameworks: items: type: string type: array title: Compliance Frameworks opened_at: type: string format: date-time title: Opened At triaged_at: anyOf: - type: string format: date-time - type: 'null' title: Triaged At resolved_at: anyOf: - type: string format: date-time - type: 'null' title: Resolved At closed_at: anyOf: - type: string format: date-time - type: 'null' title: Closed At created_at: type: string format: date-time title: Created At updated_at: type: string format: date-time title: Updated At created_by: anyOf: - type: string - type: 'null' title: Created By tags: additionalProperties: true type: object title: Tags sla_due_at: anyOf: - type: string format: date-time - type: 'null' title: Sla Due At fanout_results: anyOf: - items: $ref: '#/components/schemas/FanoutResult' type: array - type: 'null' title: Fanout Results type: object required: - id - title - description - severity - status - assignee - mitre_techniques - alert_ids - observable_graph - evidence_chain - compliance_frameworks - opened_at - triaged_at - resolved_at - closed_at - created_at - updated_at - created_by - tags - sla_due_at title: CaseResponse ChildTenantOut: properties: id: type: string format: uuid title: Id name: type: string title: Name mssp_role: type: string title: Mssp Role created_at: type: string title: Created At type: object required: - id - name - mssp_role - created_at title: ChildTenantOut CloseRequest: properties: analyst_note: anyOf: - type: string - type: 'null' title: Analyst Note type: object title: CloseRequest description: Optional analyst note appended to the auto-generated summary. ClosedSummary: properties: run_id: type: string format: uuid title: Run Id status: type: string title: Status artifact_id: type: string format: uuid title: Artifact Id summary_markdown: type: string title: Summary Markdown type: object required: - run_id - status - artifact_id - summary_markdown title: ClosedSummary description: Response body for POST /close. CollectEvidenceRequest: properties: framework: type: string title: Framework description: Compliance framework key e.g. 'SOC2'. control_id: type: string title: Control Id description: Control identifier e.g. 'CC7.2'. control_title: anyOf: - type: string - type: 'null' title: Control Title evidence_kind: type: string enum: - alert - log - screenshot - attestation - policy - runbook - other title: Evidence Kind default: alert summary: type: string minLength: 5 title: Summary raw_payload: additionalProperties: true type: object title: Raw Payload case_id: anyOf: - type: string format: uuid - type: 'null' title: Case Id type: object required: - framework - control_id - summary title: CollectEvidenceRequest CollectJobRequest: properties: framework: type: string title: Framework description: Compliance framework key e.g. 'SOC2'. scope: type: string title: Scope description: 'Collection scope: ''full'' or ''delta''.' default: full type: object required: - framework title: CollectJobRequest CollectJobResponse: properties: job_id: type: string format: uuid title: Job Id framework: type: string title: Framework scope: type: string title: Scope status: type: string title: Status queued_at: type: string format: date-time title: Queued At type: object required: - job_id - framework - scope - status - queued_at title: CollectJobResponse CommentResponse: properties: id: type: string format: uuid title: Id case_id: type: string format: uuid title: Case Id author: anyOf: - type: string - type: 'null' title: Author body: type: string title: Body is_system: type: boolean title: Is System created_at: type: string format: date-time title: Created At type: object required: - id - case_id - author - body - is_system - created_at title: CommentResponse CommunityPluginListOut: properties: total: type: integer title: Total items: items: $ref: '#/components/schemas/CommunityPluginOut' type: array title: Items type: object required: - total - items title: CommunityPluginListOut CommunityPluginOut: properties: id: type: string title: Id name: type: string title: Name version: type: string title: Version plugin_type: type: string title: Plugin Type description: type: string title: Description author: type: string title: Author tags: items: type: string type: array title: Tags default: [] status: $ref: '#/components/schemas/PublishStatus' default: pending install_count: type: integer title: Install Count default: 0 rating: type: number title: Rating default: 0.0 rating_count: type: integer title: Rating Count default: 0 verified: type: boolean title: Verified default: false submitted_at: type: string title: Submitted At approved_at: anyOf: - type: string - type: 'null' title: Approved At type: object required: - id - name - version - plugin_type - description - author - submitted_at title: CommunityPluginOut CompliancePosture: properties: framework: type: string title: Framework total_evidence: type: integer title: Total Evidence accepted: type: integer title: Accepted pending: type: integer title: Pending rejected: type: integer title: Rejected coverage_pct: type: number title: Coverage Pct controls_covered: items: type: string type: array title: Controls Covered controls_missing: items: type: string type: array title: Controls Missing generated_at: type: string format: date-time title: Generated At type: object required: - framework - total_evidence - accepted - pending - rejected - coverage_pct - controls_covered - controls_missing - generated_at title: CompliancePosture ConfidenceBucket: properties: label: type: string title: Label floor: type: integer title: Floor ceil: type: integer title: Ceil count: type: integer title: Count activeCount: type: integer title: Activecount type: object required: - label - floor - ceil - count - activeCount title: ConfidenceBucket description: 'One column in the confidence histogram. ``label`` is the human-friendly bucket label rendered on the x-axis ("0–25", "26–50", …). ``floor`` / ``ceil`` are inclusive bounds so the UI can highlight the bucket a particular rule falls into without re-parsing the label.' ConfidenceResponse: properties: summary: $ref: '#/components/schemas/ConfidenceSummary' buckets: items: $ref: '#/components/schemas/ConfidenceBucket' type: array title: Buckets tactics: items: $ref: '#/components/schemas/TacticConfidence' type: array title: Tactics lowest: items: $ref: '#/components/schemas/ConfidenceRuleEntry' type: array title: Lowest highest: items: $ref: '#/components/schemas/ConfidenceRuleEntry' type: array title: Highest generatedAt: type: string title: Generatedat type: object required: - summary - buckets - tactics - lowest - highest - generatedAt title: ConfidenceResponse ConfidenceRuleEntry: properties: ruleId: type: string title: Ruleid name: type: string title: Name severity: type: string title: Severity enabled: type: boolean title: Enabled confidence: type: integer title: Confidence fpRate: type: number title: Fprate primaryTactic: anyOf: - type: string - type: 'null' title: Primarytactic type: object required: - ruleId - name - severity - enabled - confidence - fpRate title: ConfidenceRuleEntry description: A rule highlighted in the worst/best lists. ConfidenceSummary: properties: totalRules: type: integer title: Totalrules activeRules: type: integer title: Activerules avgConfidence: type: number title: Avgconfidence avgConfidenceActive: type: number title: Avgconfidenceactive medianConfidence: type: integer title: Medianconfidence lowConfidence: type: integer title: Lowconfidence type: object required: - totalRules - activeRules - avgConfidence - avgConfidenceActive - medianConfidence - lowConfidence title: ConfidenceSummary ConnectorHealthSummary: properties: total: type: integer title: Total healthy: type: integer title: Healthy unhealthy: type: integer title: Unhealthy unknown: type: integer title: Unknown drifted: type: integer title: Drifted drifted_recently: type: integer title: Drifted Recently last_drift_at: anyOf: - type: string format: date-time - type: 'null' title: Last Drift At total_events_ingested: type: integer title: Total Events Ingested total_events_dropped: type: integer title: Total Events Dropped type: object required: - total - healthy - unhealthy - unknown - drifted - drifted_recently - last_drift_at - total_events_ingested - total_events_dropped title: ConnectorHealthSummary description: 'Tenant-wide rollup of connector health for the dashboard. The web console shows a small "Connector Health" tile at the top of the Connectors page; this endpoint feeds that tile so the UI can render it without iterating the full list client-side.' ConnectorResponse: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id name: type: string title: Name connector_type: type: string title: Connector Type category: type: string title: Category is_enabled: type: boolean title: Is Enabled connector_config: additionalProperties: true type: object title: Connector Config health_status: type: string title: Health Status last_health_check: anyOf: - type: string format: date-time - type: 'null' title: Last Health Check last_sync: anyOf: - type: string format: date-time - type: 'null' title: Last Sync events_ingested: type: integer title: Events Ingested events_dropped: type: integer title: Events Dropped default: 0 error_count: type: integer title: Error Count schema_fingerprint: anyOf: - type: string - type: 'null' title: Schema Fingerprint last_schema_drift_at: anyOf: - type: string format: date-time - type: 'null' title: Last Schema Drift At last_drift_details: anyOf: - additionalProperties: true type: object - type: 'null' title: Last Drift Details last_event_at: anyOf: - type: string format: date-time - type: 'null' title: Last Event At last_event_kind: anyOf: - type: string - type: 'null' title: Last Event Kind oauth_provisioned: type: boolean title: Oauth Provisioned default: false allowed_capabilities: anyOf: - items: type: string type: array - type: 'null' title: Allowed Capabilities freshness: anyOf: - $ref: '#/components/schemas/FreshnessSLOResponse' - type: 'null' tags: items: {} type: array title: Tags created_at: type: string format: date-time title: Created At updated_at: type: string format: date-time title: Updated At type: object required: - id - tenant_id - name - connector_type - category - is_enabled - connector_config - health_status - last_health_check - last_sync - events_ingested - error_count - tags - created_at - updated_at title: ConnectorResponse description: 'Public projection of a ``Connector`` row. ``auth_config`` is intentionally **omitted**. Even decrypted credentials should never round-trip back to the wizard — the user typed them once and they belong inside the vault from then on. Wizard-driven re-edit flows reset specific secret fields rather than reading the existing ones. ``connector_config`` *is* included because it holds non-secret runtime knobs (poll interval, region, log filters) that the wizard surfaces so an operator can tweak them without re-pasting credentials.' ControlItem: properties: control_id: type: string title: Control Id title: type: string title: Title type: object required: - control_id - title title: ControlItem ControlsResponse: properties: framework_id: type: string title: Framework Id controls: items: $ref: '#/components/schemas/ControlItem' type: array title: Controls type: object required: - framework_id - controls title: ControlsResponse CostAggregateResponse: properties: window_days: type: integer title: Window Days by_model: items: $ref: '#/components/schemas/CostAggregateRow' type: array title: By Model totals: anyOf: - $ref: '#/components/schemas/CostAggregateRow' - type: 'null' type: object required: - window_days - by_model - totals title: CostAggregateResponse CostAggregateRow: properties: model: type: string title: Model runs: type: integer title: Runs calls: type: integer title: Calls total_prompt_tokens: type: integer title: Total Prompt Tokens total_completion_tokens: type: integer title: Total Completion Tokens total_cost_usd: type: number title: Total Cost Usd total_latency_ms: type: integer title: Total Latency Ms avg_cost_per_run: type: number title: Avg Cost Per Run avg_latency_per_call_ms: type: number title: Avg Latency Per Call Ms type: object required: - model - runs - calls - total_prompt_tokens - total_completion_tokens - total_cost_usd - total_latency_ms - avg_cost_per_run - avg_latency_per_call_ms title: CostAggregateRow description: Aggregate spend grouped by model across runs. CostBucket: properties: day: type: string format: date title: Day total_cost_usd: type: number title: Total Cost Usd total_tokens: type: integer title: Total Tokens call_count: type: integer title: Call Count type: object required: - day - total_cost_usd - total_tokens - call_count title: CostBucket description: LLM spend bucketed by day. CostDashboard: properties: tenant_id: type: string format: uuid title: Tenant Id period: $ref: '#/components/schemas/DashboardPeriod' headline: $ref: '#/components/schemas/CostHeadline' daily_costs: items: $ref: '#/components/schemas/CostBucket' type: array title: Daily Costs by_model: items: $ref: '#/components/schemas/ModelBreakdown' type: array title: By Model top_cases: items: $ref: '#/components/schemas/TopCostCase' type: array title: Top Cases action_counts: items: $ref: '#/components/schemas/ActionCount' type: array title: Action Counts byok_savings: $ref: '#/components/schemas/ByokSavings' type: object required: - tenant_id - period - headline - byok_savings title: CostDashboard description: Top-level deterministic snapshot. CostHeadline: properties: total_cost_usd: type: number title: Total Cost Usd total_tokens: type: integer title: Total Tokens total_calls: type: integer title: Total Calls total_runs: type: integer title: Total Runs avg_cost_per_run_usd: anyOf: - type: number - type: 'null' title: Avg Cost Per Run Usd type: object required: - total_cost_usd - total_tokens - total_calls - total_runs - avg_cost_per_run_usd title: CostHeadline CoverageCell: properties: techniqueId: type: string title: Techniqueid tactic: anyOf: - type: string - type: 'null' title: Tactic techniqueName: anyOf: - type: string - type: 'null' title: Techniquename totalRules: type: integer title: Totalrules activeRules: type: integer title: Activerules inactiveRules: type: integer title: Inactiverules type: object required: - techniqueId - totalRules - activeRules - inactiveRules title: CoverageCell description: 'One technique cell in the rule-centric MITRE coverage heatmap. ``intensity`` is a 0-1 ratio that the heatmap uses to pick a color bucket; it''s max(activeRules, 1) / max-active-in-grid normalized client-side so we don''t have to know the global max here.' CoverageResponse: properties: tactics: items: type: string type: array title: Tactics cells: items: $ref: '#/components/schemas/CoverageCell' type: array title: Cells summary: $ref: '#/components/schemas/CoverageSummary' generatedAt: type: string title: Generatedat type: object required: - tactics - cells - summary - generatedAt title: CoverageResponse CoverageSummary: properties: totalRules: type: integer title: Totalrules activeRules: type: integer title: Activerules inactiveRules: type: integer title: Inactiverules techniques: type: integer title: Techniques coveredTechniques: type: integer title: Coveredtechniques type: object required: - totalRules - activeRules - inactiveRules - techniques - coveredTechniques title: CoverageSummary CreateApiKeyRequest: properties: name: type: string maxLength: 255 minLength: 1 title: Name description: Human-readable name scopes: items: type: string type: array title: Scopes description: Permission scopes granted to this key expires_in_days: anyOf: - type: integer maximum: 3650.0 minimum: 1.0 - type: 'null' title: Expires In Days description: TTL in days; None = never expires type: object required: - name title: CreateApiKeyRequest CreateApiKeyResponse: properties: id: type: string format: uuid title: Id name: type: string title: Name key: type: string title: Key description: Raw API key — shown ONCE, store securely prefix: type: string title: Prefix scopes: items: type: string type: array title: Scopes expires_at: anyOf: - type: string format: date-time - type: 'null' title: Expires At created_at: type: string format: date-time title: Created At type: object required: - id - name - key - prefix - scopes - expires_at - created_at title: CreateApiKeyResponse CreateBaselineRequest: properties: suite: type: string maxLength: 64 title: Suite score: type: number title: Score payload: additionalProperties: true type: object title: Payload type: object required: - suite - score title: CreateBaselineRequest CreateBody: properties: name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description language: type: string title: Language body: type: string title: Body enabled: type: boolean title: Enabled default: true tags: items: type: string type: array title: Tags mitre: items: type: string type: array title: Mitre severity: type: string title: Severity default: medium category: type: string title: Category default: custom type: object required: - name - language - body title: CreateBody CreateCaseRequest: properties: title: type: string minLength: 3 title: Title description: anyOf: - type: string - type: 'null' title: Description severity: type: string enum: - info - low - medium - high - critical title: Severity default: medium assignee: anyOf: - type: string - type: 'null' title: Assignee alert_ids: items: type: string format: uuid type: array title: Alert Ids mitre_techniques: items: type: string type: array title: Mitre Techniques compliance_frameworks: items: type: string type: array title: Compliance Frameworks tags: additionalProperties: type: string type: object title: Tags sla_due_at: anyOf: - type: string format: date-time - type: 'null' title: Sla Due At push_to_connector_ids: items: type: string format: uuid type: array title: Push To Connector Ids type: object required: - title title: CreateCaseRequest CreateConnectorRequest: properties: name: type: string maxLength: 255 minLength: 1 title: Name connector_type: type: string maxLength: 100 minLength: 1 title: Connector Type category: anyOf: - type: string maxLength: 50 - type: 'null' title: Category description: Optional override; defaults to the catalog entry's category. auth_config: additionalProperties: true type: object title: Auth Config connector_config: additionalProperties: true type: object title: Connector Config tags: items: type: string type: array title: Tags type: object required: - name - connector_type title: CreateConnectorRequest CreateHuntRequest: properties: title: type: string minLength: 3 title: Title hypothesis: type: string minLength: 10 title: Hypothesis description: Plain-English threat hypothesis. mitre_tactic: anyOf: - type: string - type: 'null' title: Mitre Tactic mitre_technique: anyOf: - type: string - type: 'null' title: Mitre Technique priority: type: string enum: - low - medium - high - critical title: Priority default: medium assigned_to: anyOf: - type: string - type: 'null' title: Assigned To tags: items: type: string type: array title: Tags type: object required: - title - hypothesis title: CreateHuntRequest CreateProposalRequest: properties: name: type: string maxLength: 255 title: Name description: anyOf: - type: string - type: 'null' title: Description rule_language: type: string maxLength: 30 title: Rule Language rule_body: type: string title: Rule Body category: type: string maxLength: 100 title: Category severity: type: string title: Severity default: medium confidence: type: integer maximum: 100.0 minimum: 0.0 title: Confidence default: 50 mitre_tactics: items: type: string type: array title: Mitre Tactics mitre_techniques: items: type: string type: array title: Mitre Techniques tags: items: type: string type: array title: Tags base_rule_id: anyOf: - type: string format: uuid - type: 'null' title: Base Rule Id type: object required: - name - rule_language - rule_body - category title: CreateProposalRequest CreateRuleRequest: properties: name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description rule_language: type: string title: Rule Language rule_body: type: string title: Rule Body category: type: string title: Category severity: type: string title: Severity default: medium confidence: type: integer title: Confidence default: 50 mitre_tactics: items: type: string type: array title: Mitre Tactics default: [] mitre_techniques: items: type: string type: array title: Mitre Techniques default: [] tags: items: type: string type: array title: Tags default: [] type: object required: - name - rule_language - rule_body - category title: CreateRuleRequest CreateSavedHuntRequest: properties: name: type: string maxLength: 160 minLength: 1 title: Name nl_query: type: string maxLength: 4000 minLength: 3 title: Nl Query language: type: string enum: - esql - kql - spl title: Language default: esql schedule: anyOf: - type: string maxLength: 120 - type: 'null' title: Schedule type: object required: - name - nl_query title: CreateSavedHuntRequest description: 'Body for ``POST /saved-hunts``. The caller supplies the NL question and a name; we translate server-side so the stored ``translated_query`` is guaranteed to match what the platform will execute (no client-side drift).' CreateSavedViewRequest: properties: view_type: type: string title: View Type name: type: string maxLength: 120 minLength: 1 title: Name filters: additionalProperties: true type: object title: Filters columns: anyOf: - items: {} type: array - additionalProperties: true type: object - type: 'null' title: Columns is_default: type: boolean title: Is Default default: false type: object required: - view_type - name title: CreateSavedViewRequest CreateTaskRequest: properties: title: type: string minLength: 1 title: Title status: type: string enum: - todo - in_progress - done title: Status default: todo assignee: anyOf: - type: string - type: 'null' title: Assignee dueAt: anyOf: - type: string format: date-time - type: 'null' title: Dueat type: object required: - title title: CreateTaskRequest CreateUserRequest: properties: email: type: string format: email title: Email username: type: string title: Username password: type: string title: Password role: type: string title: Role default: soc_analyst type: object required: - email - username - password title: CreateUserRequest CredentialsListResponse: properties: items: items: $ref: '#/components/schemas/PasskeyCredentialOut' type: array title: Items type: object required: - items title: CredentialsListResponse CrossTenantIncident: properties: incident_id: type: string title: Incident Id tenant_name: type: string title: Tenant Name title: type: string title: Title severity: type: string title: Severity status: type: string title: Status created_at: type: string title: Created At assignee: anyOf: - type: string - type: 'null' title: Assignee type: object required: - incident_id - tenant_name - title - severity - status - created_at title: CrossTenantIncident DashboardMetrics: properties: alerts: $ref: '#/components/schemas/AlertMetrics' cases: $ref: '#/components/schemas/CaseMetrics' sources: items: $ref: '#/components/schemas/SourceStat' type: array title: Sources topMitre: items: $ref: '#/components/schemas/MitreTactic' type: array title: Topmitre alertsTrend: items: $ref: '#/components/schemas/TrendPoint' type: array title: Alertstrend threatsBySource: items: $ref: '#/components/schemas/SourceThreat' type: array title: Threatsbysource type: object required: - alerts - cases - sources - topMitre - alertsTrend - threatsBySource title: DashboardMetrics DashboardPeriod: properties: start: type: string format: date-time title: Start end: type: string format: date-time title: End window_days: type: integer title: Window Days label: type: string title: Label type: object required: - start - end - window_days - label title: DashboardPeriod DecisionRequest: properties: decision: type: string enum: - approve - reject title: Decision comment: anyOf: - type: string maxLength: 2000 - type: 'null' title: Comment type: object required: - decision title: DecisionRequest DelegationCreate: properties: child_tenant_id: type: string format: uuid title: Child Tenant Id granted_role: type: string title: Granted Role default: soc_analyst expires_at: anyOf: - type: string format: date-time - type: 'null' title: Expires At type: object required: - child_tenant_id title: DelegationCreate DelegationOut: properties: child_tenant_id: type: string format: uuid title: Child Tenant Id granted_role: type: string title: Granted Role default: soc_analyst expires_at: anyOf: - type: string format: date-time - type: 'null' title: Expires At id: type: string format: uuid title: Id parent_tenant_id: type: string format: uuid title: Parent Tenant Id granted_by_user: anyOf: - type: string format: uuid - type: 'null' title: Granted By User revoked_at: anyOf: - type: string format: date-time - type: 'null' title: Revoked At created_at: type: string title: Created At type: object required: - child_tenant_id - id - parent_tenant_id - granted_by_user - revoked_at - created_at title: DelegationOut DeploymentConfig: properties: mode: $ref: '#/components/schemas/DeploymentMode' llm_provider: $ref: '#/components/schemas/LLMProvider' update_channel: $ref: '#/components/schemas/UpdateChannel' telemetry_enabled: type: boolean title: Telemetry Enabled auto_update: type: boolean title: Auto Update last_updated: type: string title: Last Updated type: object required: - mode - llm_provider - update_channel - telemetry_enabled - auto_update - last_updated title: DeploymentConfig DeploymentConfigUpdate: properties: mode: anyOf: - $ref: '#/components/schemas/DeploymentMode' - type: 'null' llm_provider: anyOf: - $ref: '#/components/schemas/LLMProvider' - type: 'null' update_channel: anyOf: - $ref: '#/components/schemas/UpdateChannel' - type: 'null' telemetry_enabled: anyOf: - type: boolean - type: 'null' title: Telemetry Enabled auto_update: anyOf: - type: boolean - type: 'null' title: Auto Update type: object title: DeploymentConfigUpdate DeploymentMode: type: string enum: - cloud - hybrid - airgap title: DeploymentMode DetectionRuleResponse: properties: id: type: string format: uuid title: Id tenant_id: anyOf: - type: string format: uuid - type: 'null' title: Tenant Id name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description rule_language: type: string title: Rule Language rule_body: type: string title: Rule Body category: type: string title: Category status: type: string title: Status severity: type: string title: Severity confidence: type: integer title: Confidence mitre_tactics: items: {} type: array title: Mitre Tactics mitre_techniques: items: {} type: array title: Mitre Techniques fp_rate: type: number title: Fp Rate total_hits: type: integer title: Total Hits last_triggered: anyOf: - type: string format: date-time - type: 'null' title: Last Triggered tags: items: {} type: array title: Tags is_builtin: type: boolean title: Is Builtin version: type: integer title: Version created_at: type: string format: date-time title: Created At updated_at: type: string format: date-time title: Updated At type: object required: - id - tenant_id - name - description - rule_language - rule_body - category - status - severity - confidence - mitre_tactics - mitre_techniques - fp_rate - total_hits - last_triggered - tags - is_builtin - version - created_at - updated_at title: DetectionRuleResponse DiscoverResponse: properties: discovered: items: type: string type: array title: Discovered type: object required: - discovered title: DiscoverResponse DismissTuningRequest: properties: reason: anyOf: - type: string maxLength: 255 - type: 'null' title: Reason type: object title: DismissTuningRequest description: Body for ``POST /detection/tuning/{rule_id}/dismiss``. DriftEntry: properties: ruleId: type: string title: Ruleid name: type: string title: Name severity: type: string title: Severity enabled: type: boolean title: Enabled confidence: type: integer title: Confidence fpRate: type: number title: Fprate lastTriggeredAt: anyOf: - type: string - type: 'null' title: Lasttriggeredat daysSinceTriggered: anyOf: - type: integer - type: 'null' title: Dayssincetriggered issues: items: type: string type: array title: Issues type: object required: - ruleId - name - severity - enabled - confidence - fpRate - issues title: DriftEntry description: 'One rule that has drifted from its tuning baseline. ``issues`` enumerates *which* heuristics flagged it; the UI renders one chip per issue so analysts see the reason without having to read the metric values.' DriftResponse: properties: entries: items: $ref: '#/components/schemas/DriftEntry' type: array title: Entries summary: $ref: '#/components/schemas/DriftSummary' generatedAt: type: string title: Generatedat type: object required: - entries - summary - generatedAt title: DriftResponse DriftSummary: properties: total: type: integer title: Total highFpRate: type: integer title: Highfprate lowConfidence: type: integer title: Lowconfidence stale: type: integer title: Stale type: object required: - total - highFpRate - lowConfidence - stale title: DriftSummary EdgeCreate: properties: source_id: type: string format: uuid title: Source Id target_id: type: string format: uuid title: Target Id edge_type: type: string title: Edge Type weight: type: number title: Weight default: 1.0 valid_until: anyOf: - type: string format: date-time - type: 'null' title: Valid Until evidence: additionalProperties: true type: object title: Evidence type: object required: - source_id - target_id - edge_type title: EdgeCreate EdgeOut: properties: source_id: type: string format: uuid title: Source Id target_id: type: string format: uuid title: Target Id edge_type: type: string title: Edge Type weight: type: number title: Weight default: 1.0 valid_until: anyOf: - type: string format: date-time - type: 'null' title: Valid Until evidence: additionalProperties: true type: object title: Evidence id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id valid_from: type: string title: Valid From created_at: type: string title: Created At type: object required: - source_id - target_id - edge_type - id - tenant_id - valid_from - created_at title: EdgeOut EffectiveRuleCountOut: properties: total: type: integer title: Total tenant: type: integer title: Tenant builtin: type: integer title: Builtin pack: type: integer title: Pack excluded: type: integer title: Excluded type: object required: - total - tenant - builtin - pack - excluded title: EffectiveRuleCountOut EffectiveRuleOut: properties: id: type: string format: uuid title: Id name: type: string title: Name rule_language: type: string title: Rule Language severity: type: string title: Severity category: anyOf: - type: string - type: 'null' title: Category status: type: string title: Status is_builtin: type: boolean title: Is Builtin source: type: string title: Source pack_ids: items: type: string format: uuid type: array title: Pack Ids severity_overridden: type: boolean title: Severity Overridden original_severity: anyOf: - type: string - type: 'null' title: Original Severity override_note: anyOf: - type: string - type: 'null' title: Override Note parameter_overrides: additionalProperties: true type: object title: Parameter Overrides type: object required: - id - name - rule_language - severity - category - status - is_builtin - source - pack_ids - severity_overridden - original_severity - override_note - parameter_overrides title: EffectiveRuleOut EntityNeighborsResponse: properties: entity_id: type: string title: Entity Id entity_type: type: string title: Entity Type source: anyOf: - $ref: '#/components/schemas/GraphNode' - type: 'null' neighbors: items: additionalProperties: true type: object type: array title: Neighbors neighbor_count: type: integer title: Neighbor Count default: 0 type: object required: - entity_id - entity_type - source - neighbors title: EntityNeighborsResponse EvalAttachRequest: properties: eval_report: additionalProperties: true type: object title: Eval Report description: Full JSON output of `python3 scripts/run_evals.py --baseline ... --max-regression-pp ...` for the candidate ruleset. max_regression_pp: type: number maximum: 50.0 minimum: 0.0 title: Max Regression Pp description: Allowed MITRE accuracy regression vs baseline, in pp. Hard-capped at 50 — anything above that is indistinguishable from disabling the regression gate entirely. default: 1.0 type: object required: - eval_report title: EvalAttachRequest description: Attach a `run_evals.py` JSON report to a proposal. EventListResponse: properties: items: items: $ref: '#/components/schemas/EventOut' type: array title: Items total: type: integer title: Total since: anyOf: - type: integer - type: 'null' title: Since next_seq: anyOf: - type: integer - type: 'null' title: Next Seq type: object required: - items - total - since - next_seq title: EventListResponse EventOut: properties: id: type: string format: uuid title: Id run_id: type: string format: uuid title: Run Id seq: type: integer title: Seq ts: type: string format: date-time title: Ts kind: type: string title: Kind agent: type: string title: Agent summary: type: string title: Summary payload: anyOf: - additionalProperties: true type: object - type: 'null' title: Payload input_hash: anyOf: - type: string - type: 'null' title: Input Hash output_hash: anyOf: - type: string - type: 'null' title: Output Hash duration_ms: type: integer title: Duration Ms type: object required: - id - run_id - seq - ts - kind - agent - summary - payload - input_hash - output_hash - duration_ms title: EventOut EvidenceReport: properties: case_id: type: string format: uuid title: Case Id title: type: string title: Title severity: type: string title: Severity status: type: string title: Status alert_count: type: integer title: Alert Count mitre_techniques: items: type: string type: array title: Mitre Techniques compliance_frameworks: items: type: string type: array title: Compliance Frameworks evidence_chain: items: additionalProperties: true type: object type: array title: Evidence Chain generated_at: type: string format: date-time title: Generated At type: object required: - case_id - title - severity - status - alert_count - mitre_techniques - compliance_frameworks - evidence_chain - generated_at title: EvidenceReport EvidenceResponse: properties: id: type: string format: uuid title: Id case_id: anyOf: - type: string format: uuid - type: 'null' title: Case Id framework: type: string title: Framework control_id: type: string title: Control Id control_title: anyOf: - type: string - type: 'null' title: Control Title evidence_kind: type: string title: Evidence Kind summary: type: string title: Summary raw_payload: additionalProperties: true type: object title: Raw Payload payload_hash: anyOf: - type: string - type: 'null' title: Payload Hash prev_hash: anyOf: - type: string - type: 'null' title: Prev Hash collected_at: type: string format: date-time title: Collected At reviewed_by: anyOf: - type: string - type: 'null' title: Reviewed By reviewed_at: anyOf: - type: string format: date-time - type: 'null' title: Reviewed At status: type: string title: Status created_at: type: string format: date-time title: Created At type: object required: - id - case_id - framework - control_id - control_title - evidence_kind - summary - raw_payload - payload_hash - prev_hash - collected_at - reviewed_by - reviewed_at - status - created_at title: EvidenceResponse ExecuteRuleRequest: properties: events: items: additionalProperties: true type: object type: array maxItems: 1000 title: Events description: Events to test the rule against type: object required: - events title: ExecuteRuleRequest description: Payload for ad-hoc rule execution. ExecuteRuleResponse: properties: rule_id: type: string title: Rule Id rule_name: type: string title: Rule Name rule_language: type: string title: Rule Language severity: type: string title: Severity matched: type: boolean title: Matched match_count: type: integer title: Match Count matched_events: items: additionalProperties: true type: object type: array title: Matched Events score: type: number title: Score error: anyOf: - type: string - type: 'null' title: Error execution_time_ms: type: number title: Execution Time Ms type: object required: - rule_id - rule_name - rule_language - severity - matched - match_count - matched_events - score - error - execution_time_ms title: ExecuteRuleResponse ExplainResponse: properties: run: $ref: '#/components/schemas/RunSummary' previous: anyOf: - $ref: '#/components/schemas/EventOut' - type: 'null' focus: $ref: '#/components/schemas/EventOut' next: anyOf: - $ref: '#/components/schemas/EventOut' - type: 'null' artifacts: items: $ref: '#/components/schemas/ArtifactDetail' type: array title: Artifacts type: object required: - run - previous - focus - next - artifacts title: ExplainResponse description: 'Why-did-the-agent-do-this view for a single step. Includes the focal event plus the immediately preceding event (the decision that led into this step) and the immediately following event (the decision the agent made afterwards). Artifacts attached to the focal event are inlined so the auditor sees the literal LLM transcript.' ExternalAssetType: type: string enum: - domain - subdomain - ip - cert - web_service - api_endpoint title: ExternalAssetType description: Types of externally-discovered assets. FanoutResult: properties: connector_id: type: string format: uuid title: Connector Id connector_type: type: string title: Connector Type connector_name: type: string title: Connector Name status: type: string title: Status description: ok | error | unsupported | skipped external_id: anyOf: - type: string - type: 'null' title: External Id external_url: anyOf: - type: string - type: 'null' title: External Url external_status: anyOf: - type: string - type: 'null' title: External Status error: anyOf: - type: string - type: 'null' title: Error type: object required: - connector_id - connector_type - connector_name - status title: FanoutResult description: 'Outcome of one ``push_case`` / ``push_status_change`` call. Always set so the UI can show "Jira ✓ · ServiceNow ✗ (timeout)" next to the case header without needing to re-read the audit log.' FederatedBackend: properties: connector_id: type: string format: uuid title: Connector Id connector_type: type: string title: Connector Type name: type: string title: Name health_status: type: string title: Health Status is_enabled: type: boolean title: Is Enabled type: object required: - connector_id - connector_type - name - health_status - is_enabled title: FederatedBackend description: Read-only projection of a connector instance eligible for fan-out. FederatedBackendsResponse: properties: backends: items: $ref: '#/components/schemas/FederatedBackend' type: array title: Backends type: object required: - backends title: FederatedBackendsResponse FederatedSearchRequest: properties: free_text: type: string maxLength: 2000 title: Free Text default: '' indicators: items: $ref: '#/components/schemas/IndicatorPayload' type: array title: Indicators since_seconds: type: integer maximum: 604800.0 exclusiveMinimum: 0.0 title: Since Seconds default: 3600 limit: type: integer maximum: 1000.0 exclusiveMinimum: 0.0 title: Limit default: 100 connector_ids: anyOf: - items: type: string format: uuid type: array - type: 'null' title: Connector Ids per_backend_timeout_seconds: anyOf: - type: number maximum: 120.0 exclusiveMinimum: 0.0 - type: 'null' title: Per Backend Timeout Seconds type: object title: FederatedSearchRequest description: 'Top-level federated search payload. ``connector_ids`` lets the caller scope the fan-out to specific instances (e.g. "only my prod Splunk, not the staging Sentinel"). Omit it to query every federated-capable connector the tenant has enabled. ``per_backend_timeout_seconds`` caps how long any one SIEM gets before we move on. Default is half the configured connectors-service timeout — long enough for a real SIEM round-trip, short enough that a single dead backend doesn''t block the merged answer.' FederatedSearchResponse: properties: rows: items: additionalProperties: true type: object type: array title: Rows row_count: type: integer title: Row Count sources: items: $ref: '#/components/schemas/SourceVerdict' type: array title: Sources truncated: type: boolean title: Truncated description: True when the merged row count was capped at ``limit`` after fan-out. default: false type: object required: - rows - row_count - sources title: FederatedSearchResponse FeedCreate: properties: name: type: string title: Name feed_type: type: string title: Feed Type url: anyOf: - type: string - type: 'null' title: Url api_key_ref: anyOf: - type: string - type: 'null' title: Api Key Ref poll_interval: type: integer title: Poll Interval default: 3600 config: additionalProperties: true type: object title: Config type: object required: - name - feed_type title: FeedCreate FeedOut: properties: name: type: string title: Name feed_type: type: string title: Feed Type url: anyOf: - type: string - type: 'null' title: Url api_key_ref: anyOf: - type: string - type: 'null' title: Api Key Ref poll_interval: type: integer title: Poll Interval default: 3600 config: additionalProperties: true type: object title: Config id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id is_enabled: type: boolean title: Is Enabled last_polled_at: anyOf: - type: string - type: 'null' title: Last Polled At created_at: type: string title: Created At type: object required: - name - feed_type - id - tenant_id - is_enabled - created_at title: FeedOut FindingCreate: properties: cloud_provider: type: string title: Cloud Provider cloud_account: anyOf: - type: string - type: 'null' title: Cloud Account cloud_region: anyOf: - type: string - type: 'null' title: Cloud Region resource_type: type: string title: Resource Type resource_id: type: string title: Resource Id resource_name: anyOf: - type: string - type: 'null' title: Resource Name rule_id: type: string title: Rule Id rule_title: type: string title: Rule Title description: anyOf: - type: string - type: 'null' title: Description severity: type: string title: Severity default: medium frameworks: anyOf: - items: type: string type: array - type: 'null' title: Frameworks control_ids: anyOf: - items: type: string type: array - type: 'null' title: Control Ids evidence: additionalProperties: true type: object title: Evidence remediation_guide: anyOf: - type: string - type: 'null' title: Remediation Guide type: object required: - cloud_provider - resource_type - resource_id - rule_id - rule_title title: FindingCreate FindingOut: properties: cloud_provider: type: string title: Cloud Provider cloud_account: anyOf: - type: string - type: 'null' title: Cloud Account cloud_region: anyOf: - type: string - type: 'null' title: Cloud Region resource_type: type: string title: Resource Type resource_id: type: string title: Resource Id resource_name: anyOf: - type: string - type: 'null' title: Resource Name rule_id: type: string title: Rule Id rule_title: type: string title: Rule Title description: anyOf: - type: string - type: 'null' title: Description severity: type: string title: Severity default: medium frameworks: anyOf: - items: type: string type: array - type: 'null' title: Frameworks control_ids: anyOf: - items: type: string type: array - type: 'null' title: Control Ids evidence: additionalProperties: true type: object title: Evidence remediation_guide: anyOf: - type: string - type: 'null' title: Remediation Guide id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id status: type: string title: Status auto_remediated: type: boolean title: Auto Remediated first_detected_at: type: string title: First Detected At last_evaluated_at: type: string title: Last Evaluated At resolved_at: anyOf: - type: string - type: 'null' title: Resolved At type: object required: - cloud_provider - resource_type - resource_id - rule_id - rule_title - id - tenant_id - status - auto_remediated - first_detected_at - last_evaluated_at title: FindingOut FinishRequest: properties: credential: additionalProperties: true type: object title: Credential challenge: type: string maxLength: 512 minLength: 8 title: Challenge type: object required: - credential - challenge title: FinishRequest FormatsResponse: properties: formats: additionalProperties: type: string type: object title: Formats type: object required: - formats title: FormatsResponse FrameworksResponse: properties: frameworks: additionalProperties: additionalProperties: type: string type: object type: object title: Frameworks type: object required: - frameworks title: FrameworksResponse FreshnessSLOResponse: properties: status: type: string title: Status expected_cadence_seconds: type: integer title: Expected Cadence Seconds seconds_since_last_event: anyOf: - type: integer - type: 'null' title: Seconds Since Last Event category: type: string title: Category type: object required: - status - expected_cadence_seconds - seconds_since_last_event - category title: FreshnessSLOResponse description: 'Freshness verdict surfaced on every ``ConnectorResponse``. Driven by ``app.services.connector_freshness.compute_freshness``. The UI uses ``status`` to color the badge and ``seconds_since_last_event`` + ``expected_cadence_seconds`` to render the tooltip ("expected within 5 min, last event 12 min ago"). ``category`` is echoed back for client-side grouping without re-deriving it.' FrontendDetectionRule: properties: id: type: string title: Id name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description language: type: string title: Language body: type: string title: Body enabled: type: boolean title: Enabled default: true tags: items: type: string type: array title: Tags mitre: items: type: string type: array title: Mitre severity: type: string title: Severity default: medium createdAt: type: string title: Createdat updatedAt: type: string title: Updatedat lastTriggeredAt: anyOf: - type: string - type: 'null' title: Lasttriggeredat hitCount: type: integer title: Hitcount default: 0 type: object required: - id - name - language - body - createdAt - updatedAt title: FrontendDetectionRule description: Mirrors `DetectionRule` in apps/web/src/lib/api.ts. FunnelDeltas: properties: events_of_interest: type: number title: Events Of Interest correlation_instances: type: number title: Correlation Instances alerts_generated: type: number title: Alerts Generated signal_to_noise: type: number title: Signal To Noise mttd_seconds: type: number title: Mttd Seconds analyst_queue_depth: type: number title: Analyst Queue Depth type: object required: - events_of_interest - correlation_instances - alerts_generated - signal_to_noise - mttd_seconds - analyst_queue_depth title: FunnelDeltas description: Period-over-period percentage deltas for the funnel KPI bar. FunnelMetrics: properties: period: type: string title: Period events_of_interest: type: integer title: Events Of Interest correlation_instances: type: integer title: Correlation Instances alerts_generated: type: integer title: Alerts Generated signal_to_noise: type: number title: Signal To Noise mttd_seconds: type: number title: Mttd Seconds analyst_queue_depth: type: integer title: Analyst Queue Depth correlation_efficiency: type: number title: Correlation Efficiency alert_yield: type: number title: Alert Yield mitre_coverage: $ref: '#/components/schemas/MitreCoverage' deltas: $ref: '#/components/schemas/FunnelDeltas' generated_at: type: string format: date-time title: Generated At type: object required: - period - events_of_interest - correlation_instances - alerts_generated - signal_to_noise - mttd_seconds - analyst_queue_depth - correlation_efficiency - alert_yield - mitre_coverage - deltas - generated_at title: FunnelMetrics description: 'Tenant funnel + efficiency for the selected period. All counts are absolute for ``period``. ``signal_to_noise`` is the fraction of *resolved* alerts that ended in disposition ``true_positive`` (i.e. signal / (signal + noise)). ``mttd_seconds`` mirrors /metrics/soc''s MTTD definition (Alert.created_at → Alert.first_seen_at) but expressed in seconds for funnel-level precision. ``deltas`` compares this period to the immediately preceding period of the same length.' GateLogOut: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id action_id: type: string format: uuid title: Action Id action_type: type: string title: Action Type blast_radius: type: string title: Blast Radius maturity_tier: type: integer title: Maturity Tier decision: type: string title: Decision rationale: anyOf: - type: string - type: 'null' title: Rationale actor: type: string title: Actor created_at: type: string title: Created At type: object required: - id - tenant_id - action_id - action_type - blast_radius - maturity_tier - decision - rationale - actor - created_at title: GateLogOut GenerateRequest: properties: title: type: string title: Title report_type: type: string title: Report Type default: board_summary period_start: type: string format: date-time title: Period Start period_end: type: string format: date-time title: Period End output_format: type: string title: Output Format default: pdf recipients: anyOf: - items: type: string type: array - type: 'null' title: Recipients type: object required: - title - period_start - period_end title: GenerateRequest GraphEdge: properties: source: type: string title: Source target: type: string title: Target type: type: string title: Type type: object required: - source - target - type title: GraphEdge GraphNode: properties: id: type: string title: Id label: type: string title: Label properties: additionalProperties: true type: object title: Properties type: object required: - id - label title: GraphNode HTTPValidationError: properties: detail: items: $ref: '#/components/schemas/ValidationError' type: array title: Detail type: object title: HTTPValidationError HandoffNotes: properties: notes: type: string minLength: 1 title: Notes pending_items: items: type: string type: array title: Pending Items type: object required: - notes title: HandoffNotes HuntPreviewItem: properties: id: type: string title: Id timestamp: type: string title: Timestamp source: type: string title: Source severity: anyOf: - type: string - type: 'null' title: Severity fields: additionalProperties: true type: object title: Fields type: object required: - id - timestamp - source title: HuntPreviewItem HuntRequest: properties: rule_ids: anyOf: - items: type: string format: uuid type: array - type: 'null' title: Rule Ids description: Specific rule IDs to hunt with; omit to use all active rules rule_language: anyOf: - type: string - type: 'null' title: Rule Language description: Filter rules by language (sigma, yara, kql, eql) events: items: additionalProperties: true type: object type: array maxItems: 5000 title: Events description: Events to hunt through type: object required: - events title: HuntRequest description: Payload for threat hunting across events. HuntRunResponse: properties: id: type: string format: uuid title: Id hunt_id: type: string format: uuid title: Hunt Id run_at: type: string format: date-time title: Run At platform: type: string title: Platform query_used: anyOf: - type: string - type: 'null' title: Query Used hit_count: type: integer title: Hit Count result_sample: items: additionalProperties: true type: object type: array title: Result Sample duration_ms: anyOf: - type: integer - type: 'null' title: Duration Ms error: anyOf: - type: string - type: 'null' title: Error type: object required: - id - hunt_id - run_at - platform - query_used - hit_count - result_sample - duration_ms - error title: HuntRunResponse IOCCreate: properties: ioc_type: type: string title: Ioc Type value: type: string title: Value confidence: type: integer maximum: 100.0 minimum: 0.0 title: Confidence default: 50 severity: type: string title: Severity default: medium tlp: type: string title: Tlp default: amber threat_actor: anyOf: - type: string - type: 'null' title: Threat Actor campaign: anyOf: - type: string - type: 'null' title: Campaign malware_family: anyOf: - type: string - type: 'null' title: Malware Family tags: anyOf: - items: type: string type: array - type: 'null' title: Tags source: type: string title: Source default: internal source_ref: anyOf: - type: string - type: 'null' title: Source Ref expires_at: anyOf: - type: string format: date-time - type: 'null' title: Expires At linked_alerts: anyOf: - items: type: string format: uuid type: array - type: 'null' title: Linked Alerts context: additionalProperties: true type: object title: Context type: object required: - ioc_type - value title: IOCCreate IOCOut: properties: ioc_type: type: string title: Ioc Type value: type: string title: Value confidence: type: integer maximum: 100.0 minimum: 0.0 title: Confidence default: 50 severity: type: string title: Severity default: medium tlp: type: string title: Tlp default: amber threat_actor: anyOf: - type: string - type: 'null' title: Threat Actor campaign: anyOf: - type: string - type: 'null' title: Campaign malware_family: anyOf: - type: string - type: 'null' title: Malware Family tags: anyOf: - items: type: string type: array - type: 'null' title: Tags source: type: string title: Source default: internal source_ref: anyOf: - type: string - type: 'null' title: Source Ref expires_at: anyOf: - type: string format: date-time - type: 'null' title: Expires At linked_alerts: anyOf: - items: type: string format: uuid type: array - type: 'null' title: Linked Alerts context: additionalProperties: true type: object title: Context id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id is_active: type: boolean title: Is Active false_positive: type: boolean title: False Positive first_seen: type: string title: First Seen last_seen: type: string title: Last Seen created_at: type: string title: Created At type: object required: - ioc_type - value - id - tenant_id - is_active - false_positive - first_seen - last_seen - created_at title: IOCOut IdentityTimeline: properties: timeline_id: type: string format: uuid title: Timeline Id identity_kind: type: string enum: - user - device - service_account - ip title: Identity Kind identity_value: type: string title: Identity Value from_ts: type: string format: date-time title: From Ts to_ts: type: string format: date-time title: To Ts events: items: $ref: '#/components/schemas/app__api__v1__endpoints__identity_timeline__TimelineEvent' type: array title: Events total_events: type: integer title: Total Events risk_score: anyOf: - type: number - type: 'null' title: Risk Score built_at: type: string format: date-time title: Built At type: object required: - timeline_id - identity_kind - identity_value - from_ts - to_ts - events - total_events - built_at title: IdentityTimeline InboundResult: properties: case_id: anyOf: - type: string format: uuid - type: 'null' title: Case Id case_number: anyOf: - type: string - type: 'null' title: Case Number external_id: anyOf: - type: string - type: 'null' title: External Id old_status: anyOf: - type: string - type: 'null' title: Old Status new_status: anyOf: - type: string - type: 'null' title: New Status status_changed: type: boolean title: Status Changed note: anyOf: - type: string - type: 'null' title: Note type: object required: - case_id - case_number - external_id - old_status - new_status - status_changed title: InboundResult description: Response body for the inbound webhook. InboxTemplateInfo: properties: template_id: type: string title: Template Id label: type: string title: Label description: type: string title: Description category: type: string title: Category type: object required: - template_id - label - description - category title: InboxTemplateInfo description: Catalog entry for a vendor template the operator can pick. InboxTokenCreate: properties: template_id: type: string title: Template Id description: Vendor template stem from ``services/ingest/internal/normalizer/templates/*.yaml`` (e.g. ``pagerduty``, ``generic-json``). label: anyOf: - type: string - type: 'null' title: Label description: Operator-facing label ("PagerDuty on-call"). hmac_secret: anyOf: - type: string maxLength: 512 minLength: 16 - type: 'null' title: Hmac Secret description: Optional HMAC-SHA256 secret for ``X-Signature`` verification. If provided, the ingest service rejects requests whose signature doesn't match. NULL means the URL token is the only authenticator. type: object required: - template_id title: InboxTokenCreate description: Request body for ``POST /api/v1/inbox/tokens``. InboxTokenListItem: properties: fingerprint: type: string title: Fingerprint template_id: type: string title: Template Id label: anyOf: - type: string - type: 'null' title: Label has_hmac_secret: type: boolean title: Has Hmac Secret created_at: type: string format: date-time title: Created At revoked_at: anyOf: - type: string format: date-time - type: 'null' title: Revoked At last_used_at: anyOf: - type: string format: date-time - type: 'null' title: Last Used At type: object required: - fingerprint - template_id - label - has_hmac_secret - created_at - revoked_at - last_used_at title: InboxTokenListItem description: 'List view: omits the plaintext token.' InboxTokenResponse: properties: token: type: string title: Token inbox_url: type: string title: Inbox Url template_id: type: string title: Template Id label: anyOf: - type: string - type: 'null' title: Label has_hmac_secret: type: boolean title: Has Hmac Secret created_at: type: string format: date-time title: Created At revoked_at: anyOf: - type: string format: date-time - type: 'null' title: Revoked At last_used_at: anyOf: - type: string format: date-time - type: 'null' title: Last Used At type: object required: - token - inbox_url - template_id - label - has_hmac_secret - created_at - revoked_at - last_used_at title: InboxTokenResponse description: 'A single inbox token, including the *plaintext* token + URL. The token is returned in full **only** at mint time (when the wizard needs to show it to the operator). Subsequent list calls return the fingerprint instead, which is enough to identify the row but not enough to forge inbound traffic.' IndicatorCreate: properties: profile_id: type: string format: uuid title: Profile Id indicator_type: type: string title: Indicator Type severity: type: string title: Severity default: medium description: type: string title: Description source_alert_id: anyOf: - type: string format: uuid - type: 'null' title: Source Alert Id evidence: additionalProperties: true type: object title: Evidence occurred_at: anyOf: - type: string format: date-time - type: 'null' title: Occurred At type: object required: - profile_id - indicator_type - description title: IndicatorCreate IndicatorListResponse: properties: items: items: $ref: '#/components/schemas/STIXIndicator' type: array title: Items total: type: integer title: Total type: object required: - items - total title: IndicatorListResponse IndicatorOut: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id profile_id: type: string format: uuid title: Profile Id indicator_type: type: string title: Indicator Type severity: type: string title: Severity description: type: string title: Description source_alert_id: anyOf: - type: string format: uuid - type: 'null' title: Source Alert Id evidence: additionalProperties: true type: object title: Evidence occurred_at: type: string title: Occurred At acknowledged_at: anyOf: - type: string - type: 'null' title: Acknowledged At type: object required: - id - tenant_id - profile_id - indicator_type - severity - description - source_alert_id - evidence - occurred_at - acknowledged_at title: IndicatorOut IndicatorPayload: properties: field: type: string maxLength: 200 minLength: 1 title: Field operator: type: string maxLength: 20 minLength: 1 title: Operator value: title: Value type: object required: - field - operator - value title: IndicatorPayload description: 'One ``field value`` triple in a federated query. Mirrors ``services.connectors.app.federated.query.Indicator`` but expressed as Pydantic so FastAPI can render OpenAPI for the wizard + the SDK. The connectors microservice re-validates with ``parse_unified_query`` before any translator runs, so this model is intentionally permissive on ``value``.' IngestRequest: properties: title: type: string minLength: 2 title: Title content: type: string minLength: 10 title: Content doc_kind: type: string enum: - runbook - policy - playbook - sop - wiki - other title: Doc Kind default: runbook source_url: anyOf: - type: string - type: 'null' title: Source Url tags: items: type: string type: array title: Tags type: object required: - title - content title: IngestRequest IngestTokenResponse: properties: connector_id: type: string format: uuid title: Connector Id ingest_token: type: string title: Ingest Token inbox_url: type: string title: Inbox Url type: object required: - connector_id - ingest_token - inbox_url title: IngestTokenResponse description: Push-token response. ``inbox_url`` is the absolute endpoint. InitialAdminUserWire: properties: id: type: string title: Id email: type: string title: Email role: type: string title: Role type: object required: - id - email - role title: InitialAdminUserWire InsightSparkline: properties: points: items: type: number type: array title: Points description: Bucket values, oldest → newest. Length == 24. type: object title: InsightSparkline description: A bucketed time-series the UI renders as a tiny inline SVG. InsightTile: properties: key: type: string title: Key description: Stable identifier — used as a React key. label: type: string title: Label description: Human-readable tile heading. value: type: number title: Value description: Headline metric for the current window. unit: type: string title: Unit description: Display unit. The UI picks formatting per unit (``hours`` → 1 decimal, ``pct`` → percentage, ``usd`` → currency, ``count`` → integer, ``hours_saved`` → integer). previous_value: type: number title: Previous Value description: Value of the same metric over the immediately preceding window of equal length. Used to compute the delta. delta_pct: anyOf: - type: number - type: 'null' title: Delta Pct description: Percentage change vs ``previous_value``. ``None`` when the previous window had no data (so the percent change is undefined rather than misleadingly infinite). sparkline: $ref: '#/components/schemas/InsightSparkline' type: object required: - key - label - value - unit - previous_value title: InsightTile description: One tile on the SOC Insights dashboard. InstallRequest: properties: type: type: string enum: - detection - playbook - plugin title: Type id: type: string maxLength: 200 minLength: 1 title: Id type: object required: - type - id title: InstallRequest InstallResponse: properties: id: type: string title: Id type: type: string title: Type name: type: string title: Name version: type: string title: Version content_sha256: type: string title: Content Sha256 installed_at: type: string title: Installed At installed_by: type: string title: Installed By already_installed: type: boolean title: Already Installed default: false type: object required: - id - type - name - version - content_sha256 - installed_at - installed_by title: InstallResponse InvestigateRequest: properties: alert_summary: anyOf: - type: string - type: 'null' title: Alert Summary default: '' type: object title: InvestigateRequest KBChunk: properties: doc_id: type: string format: uuid title: Doc Id title: type: string title: Title chunk_index: type: integer title: Chunk Index content: type: string title: Content score: anyOf: - type: number - type: 'null' title: Score type: object required: - doc_id - title - chunk_index - content title: KBChunk KBDocResponse: properties: id: type: string format: uuid title: Id title: type: string title: Title doc_kind: type: string title: Doc Kind source_url: anyOf: - type: string - type: 'null' title: Source Url tags: items: type: string type: array title: Tags chunk_index: type: integer title: Chunk Index chunk_total: type: integer title: Chunk Total content_preview: type: string title: Content Preview created_at: type: string format: date-time title: Created At created_by: anyOf: - type: string - type: 'null' title: Created By type: object required: - id - title - doc_kind - source_url - tags - chunk_index - chunk_total - content_preview - created_at - created_by title: KBDocResponse KpiBarTargetsOut: properties: false_positive_rate_max_pct: type: number maximum: 100.0 minimum: 0.0 title: False Positive Rate Max Pct alert_to_incident_ratio_min: type: number minimum: 1.0 title: Alert To Incident Ratio Min mitre_technique_tagging_min_pct: type: number maximum: 100.0 minimum: 0.0 title: Mitre Technique Tagging Min Pct mitre_subtechnique_tagging_min_pct: type: number maximum: 100.0 minimum: 0.0 title: Mitre Subtechnique Tagging Min Pct type: object required: - false_positive_rate_max_pct - alert_to_incident_ratio_min - mitre_technique_tagging_min_pct - mitre_subtechnique_tagging_min_pct title: KpiBarTargetsOut KpiBarTargetsUpdate: properties: false_positive_rate_max_pct: anyOf: - type: number maximum: 100.0 minimum: 0.0 - type: 'null' title: False Positive Rate Max Pct alert_to_incident_ratio_min: anyOf: - type: number minimum: 1.0 - type: 'null' title: Alert To Incident Ratio Min mitre_technique_tagging_min_pct: anyOf: - type: number maximum: 100.0 minimum: 0.0 - type: 'null' title: Mitre Technique Tagging Min Pct mitre_subtechnique_tagging_min_pct: anyOf: - type: number maximum: 100.0 minimum: 0.0 - type: 'null' title: Mitre Subtechnique Tagging Min Pct type: object title: KpiBarTargetsUpdate LLMProvider: type: string enum: - openai - anthropic - local-ollama - local-vllm - azure-openai - none title: LLMProvider LakeColumnInfo: properties: name: type: string title: Name type: type: string title: Type comment: type: string title: Comment default: '' type: object required: - name - type title: LakeColumnInfo description: One column within a lake table. LakeQueryRequest: properties: sql: type: string maxLength: 200000 minLength: 1 title: Sql description: 'SELECT query to run against the warm tier. The server enforces a single-statement, allowlisted-tables-only policy and injects ``tenant_id`` predicates before execution. Use ``GET /api/v1/lake/schema`` to discover available tables and columns. Allowed tables: aisoc.alert_metrics, aisoc.ioc_enrichments, aisoc.raw_events.' row_cap: anyOf: - type: integer maximum: 100000.0 minimum: 1.0 - type: 'null' title: Row Cap description: Optional ``LIMIT`` clamp; defaults to 10000, hard-capped at 100000. timeout_seconds: anyOf: - type: number maximum: 60.0 exclusiveMinimum: 0.0 - type: 'null' title: Timeout Seconds description: Optional wall-clock cap. Defaults to the server cap (30s). Useful for agent loops that need to fail fast. type: object required: - sql title: LakeQueryRequest description: 'Request body for ``POST /api/v1/lake/sql``. Only ``sql`` is required. ``row_cap`` lets an operator request a smaller-than-default result set (e.g. for paginated UIs); the rewriter clamps to :data:`MAX_ROW_CAP` regardless. ``timeout_seconds`` likewise lets the caller fail fast — useful for agent loops where a 30-second hang would compound into a wall-clock budget overrun.' LakeQueryResponse: properties: columns: items: type: string type: array title: Columns rows: items: items: {} type: array type: array title: Rows row_count: type: integer title: Row Count row_cap: type: integer title: Row Cap referenced_tables: items: type: string type: array title: Referenced Tables elapsed_ms: type: integer title: Elapsed Ms executed_at: type: string format: date-time title: Executed At type: object required: - columns - rows - row_count - row_cap - referenced_tables - elapsed_ms - executed_at title: LakeQueryResponse description: 'Response body for ``POST /api/v1/lake/sql``. ``referenced_tables`` is the set of allowlisted tables the rewriter actually touched — it''s surfaced for clients that want to flag "you queried raw_events" in a UI without re-parsing the SQL themselves.' LakeSchemaResponse: properties: tables: items: $ref: '#/components/schemas/LakeTableInfo' type: array title: Tables type: object required: - tables title: LakeSchemaResponse description: 'Response body for ``GET /api/v1/lake/schema``. Wraps the table list in an envelope so we can extend the response later (e.g. with retention info or row-count estimates) without a breaking change.' LakeTableInfo: properties: table: type: string title: Table columns: items: $ref: '#/components/schemas/LakeColumnInfo' type: array title: Columns type: object required: - table - columns title: LakeTableInfo description: One allowlisted lake table, with its columns. LastEventResponse: properties: connector_id: type: string format: uuid title: Connector Id last_event_at: anyOf: - type: string format: date-time - type: 'null' title: Last Event At last_event_kind: anyOf: - type: string - type: 'null' title: Last Event Kind events_ingested: type: integer title: Events Ingested last_sync: anyOf: - type: string format: date-time - type: 'null' title: Last Sync health_status: type: string title: Health Status data_flowing: type: boolean title: Data Flowing type: object required: - connector_id - last_event_at - last_event_kind - events_ingested - last_sync - health_status - data_flowing title: LastEventResponse description: 'Lightweight payload for the verify-data-flowing screen. The onboarding flow polls this every few seconds while waiting for the first event to land. Keeping the shape minimal avoids paying the full ``ConnectorResponse`` cost on every poll tick.' ListResponse: properties: rules: items: $ref: '#/components/schemas/FrontendDetectionRule' type: array title: Rules total: type: integer title: Total type: object required: - rules - total title: ListResponse LlmCredentialUpsert: properties: provider: type: string enum: - openai - anthropic - azure-openai - local-ollama - local-vllm - local-litellm - custom title: Provider base_url: anyOf: - type: string maxLength: 512 - type: 'null' title: Base Url model: anyOf: - type: string maxLength: 120 - type: 'null' title: Model api_key: anyOf: - type: string maxLength: 4096 - type: 'null' title: Api Key settings: anyOf: - additionalProperties: true type: object - type: 'null' title: Settings enabled: type: boolean title: Enabled default: true type: object required: - provider title: LlmCredentialUpsert description: 'Payload for ``PUT /api/v1/llm/credentials``. ``api_key`` is intentionally optional. Sending ``null`` (or omitting it) on an *existing* row keeps the stored ciphertext untouched — that lets operators flip ``enabled``, swap ``model``, or change the ``base_url`` without re-typing a 100-character secret. On a *new* row, ``api_key`` is required when the chosen provider mandates one (we surface a 422 in that case rather than silently storing NULL).' LlmCredentialView: properties: provider: type: string enum: - openai - anthropic - azure-openai - local-ollama - local-vllm - local-litellm - custom title: Provider base_url: anyOf: - type: string - type: 'null' title: Base Url model: anyOf: - type: string - type: 'null' title: Model has_api_key: type: boolean title: Has Api Key settings: additionalProperties: true type: object title: Settings enabled: type: boolean title: Enabled created_at: type: string format: date-time title: Created At updated_at: type: string format: date-time title: Updated At last_rotated_at: anyOf: - type: string format: date-time - type: 'null' title: Last Rotated At type: object required: - provider - base_url - model - has_api_key - settings - enabled - created_at - updated_at - last_rotated_at title: LlmCredentialView description: 'Read-only projection of :class:`TenantLlmCredential`. The plaintext key is intentionally absent. ``has_api_key`` is the only signal we expose — same convention the OAuth credential view uses (``has_secret``).' LoginRequest: properties: email: type: string format: email title: Email password: type: string title: Password type: object required: - email - password title: LoginRequest MSSPKpiOverview: properties: total_tenants: type: integer title: Total Tenants total_open_alerts: type: integer title: Total Open Alerts total_critical_incidents: type: integer title: Total Critical Incidents avg_health_score: type: number title: Avg Health Score avg_mttr_minutes: type: number title: Avg Mttr Minutes sla_breach_count: type: integer title: Sla Breach Count connectors_online: type: integer title: Connectors Online connectors_degraded: type: integer title: Connectors Degraded type: object required: - total_tenants - total_open_alerts - total_critical_incidents - avg_health_score - avg_mttr_minutes - sla_breach_count - connectors_online - connectors_degraded title: MSSPKpiOverview ManagedTenantRow: properties: tenant_id: type: string title: Tenant Id name: type: string title: Name health_score: type: number title: Health Score open_alerts: type: integer title: Open Alerts critical_alerts: type: integer title: Critical Alerts sla_breaches: type: integer title: Sla Breaches connector_status: type: string title: Connector Status last_event_at: type: string title: Last Event At type: object required: - tenant_id - name - health_score - open_alerts - critical_alerts - sla_breaches - connector_status - last_event_at title: ManagedTenantRow MarketplaceItemSummary: properties: id: type: string title: Id type: type: string title: Type name: type: string title: Name description: type: string title: Description default: '' version: type: string title: Version default: 1.0.0 severity: anyOf: - type: string - type: 'null' title: Severity category: anyOf: - type: string - type: 'null' title: Category source: type: string title: Source default: core verified: type: boolean title: Verified default: false sdks: items: type: string type: array title: Sdks default: [] mitre_techniques: items: type: string type: array title: Mitre Techniques default: [] tags: items: type: string type: array title: Tags default: [] type: object required: - id - type - name title: MarketplaceItemSummary MarketplaceListResponse: properties: total: type: integer title: Total stats: additionalProperties: true type: object title: Stats mitre_coverage: additionalProperties: true type: object title: Mitre Coverage items: items: $ref: '#/components/schemas/MarketplaceItemSummary' type: array title: Items installed_ids: items: type: string type: array title: Installed Ids type: object required: - total - stats - mitre_coverage - items - installed_ids title: MarketplaceListResponse MaturityConfig: properties: maturity_tier: type: integer maximum: 4.0 minimum: 0.0 title: Maturity Tier action_overrides: additionalProperties: true type: object title: Action Overrides type: object required: - maturity_tier title: MaturityConfig MaturityOut: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id maturity_tier: type: integer title: Maturity Tier action_overrides: additionalProperties: true type: object title: Action Overrides changed_at: type: string title: Changed At created_at: type: string title: Created At type: object required: - id - tenant_id - maturity_tier - action_overrides - changed_at - created_at title: MaturityOut MetricsOut: properties: tenant_id: type: string format: uuid title: Tenant Id snapshot_at: type: string title: Snapshot At open_alerts: type: integer title: Open Alerts critical_alerts: type: integer title: Critical Alerts open_cases: type: integer title: Open Cases mttr_minutes: anyOf: - type: number - type: 'null' title: Mttr Minutes sla_breaches: type: integer title: Sla Breaches connector_count: type: integer title: Connector Count health_score: anyOf: - type: number - type: 'null' title: Health Score type: object required: - tenant_id - snapshot_at - open_alerts - critical_alerts - open_cases - mttr_minutes - sla_breaches - connector_count - health_score title: MetricsOut MiniTimelineEvent: properties: id: type: string title: Id ts: type: string format: date-time title: Ts kind: type: string title: Kind description: audit | case_comment | status_change | investigation | … agent: type: string title: Agent description: actor — system | analyst@… | agent-id summary: type: string title: Summary description: One-line description, plain text payload: anyOf: - additionalProperties: true type: object - type: 'null' title: Payload duration_ms: type: integer title: Duration Ms default: 0 type: object required: - id - ts - kind - agent - summary title: MiniTimelineEvent description: 'One event in the alert''s condensed timeline. Modelled after ``LedgerEvent`` in the ledger UI so the rail can reuse the same row renderer. Fields the rail doesn''t need (``input_hash``/``output_hash``/``duration_ms``) are always ``None``/``0`` for non-investigation events. The frontend knows to hide those affordances when they''re empty.' MispDryRunRequest: properties: indicator: anyOf: - $ref: '#/components/schemas/STIXIndicatorCreate' - type: 'null' bundle: anyOf: - $ref: '#/components/schemas/STIXBundleCreate' - type: 'null' distribution: anyOf: - type: integer maximum: 4.0 minimum: 0.0 - type: 'null' title: Distribution threat_level: anyOf: - type: integer maximum: 4.0 minimum: 1.0 - type: 'null' title: Threat Level analysis: anyOf: - type: integer maximum: 2.0 minimum: 0.0 - type: 'null' title: Analysis type: object title: MispDryRunRequest description: Either ``indicator`` or ``bundle`` must be provided. MispDryRunResponse: properties: event: additionalProperties: true type: object title: Event attribute_count: type: integer title: Attribute Count skipped_count: type: integer title: Skipped Count would_push_to: anyOf: - type: string - type: 'null' title: Would Push To airgap_blocked: type: boolean title: Airgap Blocked default: false airgap_message: anyOf: - type: string - type: 'null' title: Airgap Message type: object required: - event - attribute_count - skipped_count title: MispDryRunResponse MispPushHealth: properties: configured: type: boolean title: Configured airgapped: type: boolean title: Airgapped auto_push: type: boolean title: Auto Push url: anyOf: - type: string - type: 'null' title: Url user: anyOf: - type: string - type: 'null' title: User role: anyOf: - type: string - type: 'null' title: Role ok: type: boolean title: Ok error: anyOf: - type: string - type: 'null' title: Error type: object required: - configured - airgapped - auto_push - ok title: MispPushHealth MispPushResult: properties: pushed: type: boolean title: Pushed misp_event_id: anyOf: - type: string - type: 'null' title: Misp Event Id misp_event_uuid: anyOf: - type: string - type: 'null' title: Misp Event Uuid url: anyOf: - type: string - type: 'null' title: Url pushed_attributes: anyOf: - type: integer - type: 'null' title: Pushed Attributes skipped_attributes: anyOf: - type: integer - type: 'null' title: Skipped Attributes error: anyOf: - type: string - type: 'null' title: Error type: object required: - pushed title: MispPushResult description: Embedded in a STIX response when ``push_to_misp=true``. MitreCoverage: properties: covered: type: integer title: Covered total: type: integer title: Total ratio: type: number title: Ratio type: object required: - covered - total - ratio title: MitreCoverage description: "Slice of the MITRE ATT&CK landscape we have observable coverage\ \ for.\n\n``covered`` counts the distinct techniques observed via either:\n\ \ * a tenant alert in the selected window (``Alert.mitre_techniques``), or\n\ \ * an enabled tenant/platform detection rule\n (``DetectionRule.mitre_techniques``\ \ where ``status == 'enabled'``).\n\n``total`` is configurable via ``AISOC_FUNNEL_MITRE_TOTAL``\ \ and defaults to\nthe MITRE ATT&CK Enterprise v17 technique count (201) so\ \ the ratio is\ninterpretable as \"% of ATT&CK we're watching for\". The ratio\ \ is clamped to\n``[0.0, 1.0]`` even if operators downsize the universe." MitreCoverageCell: properties: techniqueId: type: string title: Techniqueid techniqueName: type: string title: Techniquename tactic: type: string title: Tactic detections: type: integer title: Detections alerts: type: integer title: Alerts intensity: type: number title: Intensity type: object required: - techniqueId - techniqueName - tactic - detections - alerts - intensity title: MitreCoverageCell MitreCoverageItem: properties: technique_id: type: string title: Technique Id name: anyOf: - type: string - type: 'null' title: Name tactic: anyOf: - type: string - type: 'null' title: Tactic alert_count: type: integer title: Alert Count type: object required: - technique_id - name - tactic - alert_count title: MitreCoverageItem MitreCoverageResponse: properties: tactics: items: type: string type: array title: Tactics cells: items: $ref: '#/components/schemas/MitreCoverageCell' type: array title: Cells generatedAt: type: string title: Generatedat type: object required: - tactics - cells - generatedAt title: MitreCoverageResponse MitreTactic: properties: tactic: type: string title: Tactic count: type: integer title: Count type: object required: - tactic - count title: MitreTactic ModelBreakdown: properties: model: type: string title: Model runs: type: integer title: Runs calls: type: integer title: Calls total_prompt_tokens: type: integer title: Total Prompt Tokens total_completion_tokens: type: integer title: Total Completion Tokens total_cost_usd: type: number title: Total Cost Usd imputed_public_cost_usd: type: number title: Imputed Public Cost Usd avg_latency_ms: anyOf: - type: number - type: 'null' title: Avg Latency Ms type: object required: - model - runs - calls - total_prompt_tokens - total_completion_tokens - total_cost_usd - imputed_public_cost_usd - avg_latency_ms title: ModelBreakdown description: Spend / volume rolled up per model over the window. ModelCostBreakdown: properties: model: type: string title: Model total_prompt_tokens: type: integer title: Total Prompt Tokens total_completion_tokens: type: integer title: Total Completion Tokens total_cost_usd: type: number title: Total Cost Usd total_latency_ms: type: integer title: Total Latency Ms call_count: type: integer title: Call Count type: object required: - model - total_prompt_tokens - total_completion_tokens - total_cost_usd - total_latency_ms - call_count title: ModelCostBreakdown description: 'Per-model cost telemetry for a single run. Sourced from ``aisoc_run_costs`` (populated by ``CostTracker`` in the agents service). Lets operators audit which model drove spend on a given investigation.' NLDetectionRequest: properties: description: type: string maxLength: 2000 minLength: 10 title: Description description: Plain-English description of the threat behaviour to detect. target_platforms: items: type: string enum: - sigma - kql - spl - esql type: array title: Target Platforms description: Which rule languages to generate. default: - sigma - kql - spl - esql severity: type: string enum: - informational - low - medium - high - critical title: Severity default: medium mitre_techniques: items: type: string type: array title: Mitre Techniques type: object required: - description title: NLDetectionRequest NLDetectionResponse: properties: description: type: string title: Description sigma: anyOf: - type: string - type: 'null' title: Sigma kql: anyOf: - type: string - type: 'null' title: Kql spl: anyOf: - type: string - type: 'null' title: Spl esql: anyOf: - type: string - type: 'null' title: Esql model_used: type: string title: Model Used type: object required: - description - model_used title: NLDetectionResponse NLQueryExecuteRequest: properties: question: type: string minLength: 10 title: Question description: Plain-English security question (e.g. 'Show failed logins per user in the last 24 h'). index_pattern: type: string title: Index Pattern description: Elasticsearch index pattern to scope the ES|QL query. default: logs-*,aisoc-events-* time_range_hours: type: integer maximum: 8760.0 minimum: 1.0 title: Time Range Hours description: Look-back window in hours. default: 24 es_url: anyOf: - type: string - type: 'null' title: Es Url description: Override Elasticsearch URL (defaults to settings.ES_URL if set). es_api_key: anyOf: - type: string - type: 'null' title: Es Api Key description: Override ES API key (defaults to settings.ES_API_KEY if set). max_rows: type: integer maximum: 5000.0 minimum: 1.0 title: Max Rows default: 500 type: object required: - question title: NLQueryExecuteRequest NLQueryExecuteResponse: properties: request_id: type: string format: uuid title: Request Id question: type: string title: Question esql: type: string title: Esql spl: type: string title: Spl kql: type: string title: Kql explanation: type: string title: Explanation created_at: type: string format: date-time title: Created At engine: type: string title: Engine description: '`deterministic` or `llm`.' default: deterministic grammar_validated: type: boolean title: Grammar Validated description: True if every emitted query passed grammar checks. default: true result: anyOf: - $ref: '#/components/schemas/QueryResult' - type: 'null' execution_error: anyOf: - type: string - type: 'null' title: Execution Error type: object required: - request_id - question - esql - spl - kql - explanation - created_at title: NLQueryExecuteResponse NLQueryTranslateRequest: properties: question: type: string minLength: 10 title: Question description: Plain-English security question (e.g. 'Show failed logins per user in the last 24 h'). index_pattern: type: string title: Index Pattern description: Elasticsearch index pattern to scope the ES|QL query. default: logs-*,aisoc-events-* time_range_hours: type: integer maximum: 8760.0 minimum: 1.0 title: Time Range Hours description: Look-back window in hours. default: 24 type: object required: - question title: NLQueryTranslateRequest NLQueryTranslateResponse: properties: request_id: type: string format: uuid title: Request Id question: type: string title: Question esql: type: string title: Esql spl: type: string title: Spl kql: type: string title: Kql explanation: type: string title: Explanation created_at: type: string format: date-time title: Created At engine: type: string title: Engine description: '`deterministic` or `llm`.' default: deterministic grammar_validated: type: boolean title: Grammar Validated description: True if every emitted query passed grammar checks. default: true type: object required: - request_id - question - esql - spl - kql - explanation - created_at title: NLQueryTranslateResponse NodeCreate: properties: node_type: type: string title: Node Type external_id: type: string title: External Id display_name: anyOf: - type: string - type: 'null' title: Display Name source_system: type: string title: Source System risk_score: type: number title: Risk Score default: 0.0 privilege_tier: type: integer title: Privilege Tier default: 0 last_activity: anyOf: - type: string format: date-time - type: 'null' title: Last Activity attributes: additionalProperties: true type: object title: Attributes type: object required: - node_type - external_id - source_system title: NodeCreate NodeOut: properties: node_type: type: string title: Node Type external_id: type: string title: External Id display_name: anyOf: - type: string - type: 'null' title: Display Name source_system: type: string title: Source System risk_score: type: number title: Risk Score default: 0.0 privilege_tier: type: integer title: Privilege Tier default: 0 last_activity: anyOf: - type: string format: date-time - type: 'null' title: Last Activity attributes: additionalProperties: true type: object title: Attributes id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id is_active: type: boolean title: Is Active created_at: type: string title: Created At updated_at: type: string title: Updated At type: object required: - node_type - external_id - source_system - id - tenant_id - is_active - created_at - updated_at title: NodeOut OAuthAppRegistration: properties: client_id: type: string maxLength: 512 minLength: 1 title: Client Id client_secret: type: string maxLength: 4096 minLength: 1 title: Client Secret authorize_url: anyOf: - type: string maxLength: 512 - type: 'null' title: Authorize Url token_url: anyOf: - type: string maxLength: 512 - type: 'null' title: Token Url scopes: anyOf: - items: type: string type: array maxItems: 64 - type: 'null' title: Scopes type: object required: - client_id - client_secret title: OAuthAppRegistration description: Payload for ``PUT /api/v1/oauth/app/{connector_type}``. OAuthAppView: properties: connector_type: type: string title: Connector Type client_id: type: string title: Client Id has_secret: type: boolean title: Has Secret authorize_url: anyOf: - type: string - type: 'null' title: Authorize Url token_url: anyOf: - type: string - type: 'null' title: Token Url scopes: anyOf: - items: type: string type: array - type: 'null' title: Scopes created_at: type: string format: date-time title: Created At updated_at: type: string format: date-time title: Updated At type: object required: - connector_type - client_id - has_secret - authorize_url - token_url - scopes - created_at - updated_at title: OAuthAppView description: 'Read-only projection of an :class:`OAuthAppCredential`. Never round-trips the secret — only ``has_secret: bool`` so the UI can render a "credential present, last updated X days ago" badge.' ObservableEdge: properties: source: type: string title: Source target: type: string title: Target relation: type: string title: Relation type: object required: - source - target - relation title: ObservableEdge ObservableNode: properties: id: type: string title: Id kind: type: string enum: - ip - user - host - domain - hash - file - process - alert title: Kind value: type: string title: Value tags: items: type: string type: array title: Tags type: object required: - id - kind - value title: ObservableNode OnCallEntry: properties: user_id: type: string format: uuid title: User Id user_email: anyOf: - type: string - type: 'null' title: User Email user_name: anyOf: - type: string - type: 'null' title: User Name status: type: string title: Status schedule_ref: anyOf: - type: string - type: 'null' title: Schedule Ref rotation: anyOf: - type: string - type: 'null' title: Rotation note: anyOf: - type: string - type: 'null' title: Note until: anyOf: - type: string format: date-time - type: 'null' title: Until updated_at: type: string format: date-time title: Updated At type: object required: - user_id - status - updated_at title: OnCallEntry OnCallListResponse: properties: items: items: $ref: '#/components/schemas/OnCallEntry' type: array title: Items total: type: integer title: Total type: object required: - items - total title: OnCallListResponse OnCallUpdateRequest: properties: status: type: string enum: - available - busy - offline - snoozed title: Status note: anyOf: - type: string maxLength: 500 - type: 'null' title: Note snooze_minutes: anyOf: - type: integer maximum: 1440.0 minimum: 1.0 - type: 'null' title: Snooze Minutes rotation: anyOf: - type: string maxLength: 80 - type: 'null' title: Rotation schedule_ref: anyOf: - type: string maxLength: 200 - type: 'null' title: Schedule Ref type: object required: - status title: OnCallUpdateRequest OverrideEntryModel: properties: key: type: string title: Key tags: items: type: string type: array title: Tags reason: anyOf: - type: string - type: 'null' title: Reason created_at: anyOf: - type: string - type: 'null' title: Created At value: additionalProperties: true type: object title: Value type: object required: - key - tags - reason - created_at - value title: OverrideEntryModel OverrideSummaryResponse: properties: total_overrides: type: integer title: Total Overrides false_positive_corrections: type: integer title: False Positive Corrections true_positive_corrections: type: integer title: True Positive Corrections benign_corrections: type: integer title: Benign Corrections escalate_corrections: type: integer title: Escalate Corrections type: object required: - total_overrides - false_positive_corrections - true_positive_corrections - benign_corrections - escalate_corrections title: OverrideSummaryResponse PackAssignmentCreate: properties: child_tenant_id: type: string format: uuid title: Child Tenant Id enabled: type: boolean title: Enabled default: true parameter_overrides: additionalProperties: true type: object title: Parameter Overrides default: {} type: object required: - child_tenant_id title: PackAssignmentCreate PackAssignmentOut: properties: id: type: string format: uuid title: Id pack_id: type: string format: uuid title: Pack Id child_tenant_id: type: string format: uuid title: Child Tenant Id enabled: type: boolean title: Enabled parameter_overrides: additionalProperties: true type: object title: Parameter Overrides created_at: type: string title: Created At type: object required: - id - pack_id - child_tenant_id - enabled - parameter_overrides - created_at title: PackAssignmentOut PasskeyCredentialOut: properties: id: type: string format: uuid title: Id device_name: type: string title: Device Name transports: items: type: string type: array title: Transports is_discoverable: type: boolean title: Is Discoverable last_used_at: anyOf: - type: string format: date-time - type: 'null' title: Last Used At created_at: type: string format: date-time title: Created At type: object required: - id - device_name - transports - is_discoverable - last_used_at - created_at title: PasskeyCredentialOut PeerGroupCreate: properties: name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description criteria: additionalProperties: true type: object title: Criteria type: object required: - name title: PeerGroupCreate PeerGroupOut: properties: name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description criteria: additionalProperties: true type: object title: Criteria id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id created_at: type: string title: Created At type: object required: - name - id - tenant_id - created_at title: PeerGroupOut PermissionOut: properties: id: type: string format: uuid title: Id name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description category: anyOf: - type: string - type: 'null' title: Category type: object required: - id - name - description - category title: PermissionOut PipelineHealth: properties: overall_status: type: string title: Overall Status stages: items: $ref: '#/components/schemas/PipelineStage' type: array title: Stages generated_at: type: string format: date-time title: Generated At type: object required: - overall_status - stages - generated_at title: PipelineHealth description: Top-level response for ``GET /health/pipeline``. PipelineStage: properties: stage: type: string title: Stage backlog: type: integer title: Backlog p95_latency_ms: type: number title: P95 Latency Ms error_rate: type: number title: Error Rate status: type: string title: Status type: object required: - stage - backlog - p95_latency_ms - error_rate - status title: PipelineStage description: 'One row in the pipeline health strip. ``status`` follows the green/yellow/red/unknown ladder used by ``app.services.connector_freshness``. ``backlog`` is the number of items currently waiting at this stage (e.g. enabled-but-stale connectors for ``ingest``, unacked alerts for ``alert``). ``p95_latency_ms`` is the 95th percentile end-to-end latency for items that traversed this stage in the last hour. ``error_rate`` is errors / processed in the same window.' PluginManifestOut: properties: id: type: string title: Id name: type: string title: Name version: type: string title: Version plugin_type: type: string title: Plugin Type description: type: string title: Description author: type: string title: Author tags: items: type: string type: array title: Tags config_schema: additionalProperties: true type: object title: Config Schema type: object required: - id - name - version - plugin_type - description - author - tags - config_schema title: PluginManifestOut PluginOut: properties: id: type: string title: Id manifest: $ref: '#/components/schemas/PluginManifestOut' enabled: type: boolean title: Enabled loaded_at: type: number title: Loaded At error: anyOf: - type: string - type: 'null' title: Error type: object required: - id - manifest - enabled - loaded_at - error title: PluginOut PostureSummary: properties: total: type: integer title: Total critical: type: integer title: Critical high: type: integer title: High medium: type: integer title: Medium low: type: integer title: Low open: type: integer title: Open resolved: type: integer title: Resolved suppressed: type: integer title: Suppressed type: object required: - total - critical - high - medium - low - open - resolved - suppressed title: PostureSummary PreferencesPatch: properties: preferences: additionalProperties: true type: object title: Preferences type: object required: - preferences title: PreferencesPatch description: Partial update payload for user preferences (merged server-side). PreviewRequest: properties: yaml: type: string maxLength: 262144 title: Yaml alerts: items: additionalProperties: true type: object type: array title: Alerts type: object required: - yaml title: PreviewRequest PreviewResponse: properties: sample_size: type: integer title: Sample Size changed_count: type: integer title: Changed Count suppressed_count: type: integer title: Suppressed Count elapsed_ms: type: number title: Elapsed Ms rows: items: $ref: '#/components/schemas/PreviewRow' type: array title: Rows type: object required: - sample_size - changed_count - suppressed_count - elapsed_ms - rows title: PreviewResponse PreviewRow: properties: alert_id: type: string title: Alert Id matched_rule_ids: items: type: string type: array title: Matched Rule Ids before: additionalProperties: true type: object title: Before after: additionalProperties: true type: object title: After suppressed: type: boolean title: Suppressed changed: type: boolean title: Changed type: object required: - alert_id - matched_rule_ids - before - after - suppressed - changed title: PreviewRow ProposalResponse: properties: id: type: string format: uuid title: Id tenant_id: anyOf: - type: string format: uuid - type: 'null' title: Tenant Id base_rule_id: anyOf: - type: string format: uuid - type: 'null' title: Base Rule Id promoted_rule_id: anyOf: - type: string format: uuid - type: 'null' title: Promoted Rule Id name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description rule_language: type: string title: Rule Language rule_body: type: string title: Rule Body category: type: string title: Category severity: type: string title: Severity confidence: type: integer title: Confidence mitre_tactics: items: {} type: array title: Mitre Tactics mitre_techniques: items: {} type: array title: Mitre Techniques tags: items: {} type: array title: Tags status: type: string title: Status eval_result: additionalProperties: true type: object title: Eval Result review_comments: items: {} type: array title: Review Comments proposed_by_id: anyOf: - type: string format: uuid - type: 'null' title: Proposed By Id decided_by_id: anyOf: - type: string format: uuid - type: 'null' title: Decided By Id decision_comment: anyOf: - type: string - type: 'null' title: Decision Comment decided_at: anyOf: - type: string format: date-time - type: 'null' title: Decided At github_pr_url: anyOf: - type: string - type: 'null' title: Github Pr Url created_at: type: string format: date-time title: Created At updated_at: type: string format: date-time title: Updated At type: object required: - id - tenant_id - base_rule_id - promoted_rule_id - name - description - rule_language - rule_body - category - severity - confidence - mitre_tactics - mitre_techniques - tags - status - eval_result - review_comments - proposed_by_id - decided_by_id - decision_comment - decided_at - created_at - updated_at title: ProposalResponse PublishStatus: type: string enum: - pending - approved - rejected title: PublishStatus QueryRequest: properties: question: type: string minLength: 3 title: Question doc_kinds: items: type: string enum: - runbook - policy - playbook - sop - wiki - other type: array title: Doc Kinds top_k: type: integer maximum: 20.0 minimum: 1.0 title: Top K default: 5 synthesise: type: boolean title: Synthesise description: Use LLM to synthesise an answer from retrieved chunks. default: true type: object required: - question title: QueryRequest QueryResponse: properties: question: type: string title: Question chunks: items: $ref: '#/components/schemas/KBChunk' type: array title: Chunks answer: anyOf: - type: string - type: 'null' title: Answer sources: items: type: string type: array title: Sources type: object required: - question - chunks - answer - sources title: QueryResponse QueryResult: properties: columns: items: type: string type: array title: Columns rows: items: items: {} type: array type: array title: Rows total_rows: type: integer title: Total Rows took_ms: anyOf: - type: integer - type: 'null' title: Took Ms type: object required: - columns - rows - total_rows title: QueryResult QueueAction: properties: priority: type: integer title: Priority action: type: string title: Action risk: type: string title: Risk default: low type: object required: - priority - action title: QueueAction description: 'Top suggested next action for a queue row. Sourced from ``Alert.ai_recommendations``. The lowest-priority integer wins (1 = most urgent). String-only legacy values are accepted and mapped to ``risk="low"`` with the array index as a fallback priority.' QueueAsset: properties: kind: type: string title: Kind description: host | user | ip | asset value: type: string title: Value label: anyOf: - type: string - type: 'null' title: Label type: object required: - kind - value title: QueueAsset description: 'Lightweight asset descriptor for a queue row. The queue surfaces *one* representative entity per alert so the row is informative at a glance ("VPN brute force on `web-01`") without enumerating every entity. The full pivotable list lives on the Investigation Rail when the analyst opens the alert.' QueueItem: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id title: type: string title: Title severity: type: string title: Severity status: type: string title: Status priority: type: integer title: Priority category: anyOf: - type: string - type: 'null' title: Category connector_type: anyOf: - type: string - type: 'null' title: Connector Type assigned_to_id: anyOf: - type: string format: uuid - type: 'null' title: Assigned To Id case_id: anyOf: - type: string format: uuid - type: 'null' title: Case Id first_seen: type: string format: date-time title: First Seen sla_due_at: type: string format: date-time title: Sla Due At sla_remaining_seconds: type: integer title: Sla Remaining Seconds sla_breached: type: boolean title: Sla Breached age_seconds: type: integer title: Age Seconds asset: anyOf: - $ref: '#/components/schemas/QueueAsset' - type: 'null' suggested_action: anyOf: - $ref: '#/components/schemas/QueueAction' - type: 'null' bucket: type: string enum: - mine - unassigned title: Bucket type: object required: - id - tenant_id - title - severity - status - priority - first_seen - sla_due_at - sla_remaining_seconds - sla_breached - age_seconds - bucket title: QueueItem description: 'One row in the Investigation Queue workbench. Intentionally slimmer than ``AlertResponse``. The queue exists to answer "what should I work on next?" — clicking a row navigates to ``/alerts/{id}`` which loads full detail via the existing detail endpoint (``GET /alerts/{id}``). Keeping this payload small means a busy SOC with thousands of open alerts can refresh the queue cheaply (the badge on the topbar polls it).' QueueResponse: properties: items: items: $ref: '#/components/schemas/QueueItem' type: array title: Items total: type: integer title: Total counts: additionalProperties: type: integer type: object title: Counts period: type: string title: Period owner: type: string title: Owner page: type: integer title: Page page_size: type: integer title: Page Size pages: type: integer title: Pages generated_at: type: string format: date-time title: Generated At type: object required: - items - total - counts - period - owner - page - page_size - pages - generated_at title: QueueResponse description: 'Paginated queue response. ``counts`` always reports both buckets so the workbench can render the "mine / unassigned / all" tabs without re-fetching. ``generated_at`` is the server-side ``now`` we used to compute SLA remaining — the frontend can drift its own clock from this so multiple analysts on different boxes see the same countdowns.' RatingIn: properties: score: type: integer maximum: 5.0 minimum: 1.0 title: Score comment: anyOf: - type: string - type: 'null' title: Comment type: object required: - score title: RatingIn RealtimeTicket: properties: token: type: string title: Token description: Signed HS256 ticket for the WS/SSE edge. expires_in: type: integer title: Expires In description: Ticket lifetime in seconds. tenant_id: type: string title: Tenant Id description: Tenant the ticket is scoped to. type: object required: - token - expires_in - tenant_id title: RealtimeTicket description: Response body for ``POST /realtime/ticket``. RecommendedAction: properties: priority: type: integer minimum: 1.0 title: Priority default: 99 action: type: string title: Action rationale: anyOf: - type: string - type: 'null' title: Rationale risk: type: string title: Risk description: low | medium | high default: low type: object required: - action title: RecommendedAction description: 'Structured action emitted by the ResponderAgent at investigation close. Tolerates the legacy list-of-strings shape that older demo seeds used (string → ``action`` with priority ``99`` and risk ``"low"``). The plan calls for the structured shape; this is a migration aid.' RedispositionApplyRequest: properties: alert_ids: items: type: string type: array title: Alert Ids new_disposition: type: string title: New Disposition type: object required: - alert_ids - new_disposition title: RedispositionApplyRequest RedispositionApplyResponse: properties: updated: type: integer title: Updated new_disposition: type: string title: New Disposition type: object required: - updated - new_disposition title: RedispositionApplyResponse RedispositionCandidateModel: properties: alert_id: type: string title: Alert Id title: type: string title: Title severity: type: string title: Severity current_disposition: anyOf: - type: string - type: 'null' title: Current Disposition proposed_disposition: type: string title: Proposed Disposition event_time: type: string title: Event Time type: object required: - alert_id - title - severity - current_disposition - proposed_disposition - event_time title: RedispositionCandidateModel RefreshRequest: properties: refresh_token: type: string title: Refresh Token type: object required: - refresh_token title: RefreshRequest RegisterBeginRequest: properties: device_name: type: string maxLength: 120 title: Device Name default: My phone type: object title: RegisterBeginRequest RelatedEntity: properties: group: type: string title: Group description: 'Rail column: principal | network | workflow | tenant' kind: type: string title: Kind description: 'Concrete entity type: host | ip | user | rule | mitre | …' value: type: string title: Value description: Canonical identifier rendered in the chip label: anyOf: - type: string - type: 'null' title: Label description: Optional human-friendly label pivot: anyOf: - type: string - type: 'null' title: Pivot description: Frontend route to deep-link into AttackGraphView (or another workbench). When None the chip is informational only. type: object required: - group - kind - value title: RelatedEntity description: 'One pivotable entity attached to an alert. The ``kind`` field is the *concrete* entity type (``host``, ``ip``, ``user``, ``rule``, …) — the frontend keys icons and pivot routes off it. The ``group`` field is the rail column the entity renders under (``principal``, ``network``, ``workflow``, ``tenant``). One entity belongs to exactly one group; we don''t duplicate rows.' ReplaceRulesRequest: properties: yaml: type: string maxLength: 262144 title: Yaml type: object required: - yaml title: ReplaceRulesRequest ReviewAction: properties: action: type: string pattern: ^(approve|reject)$ title: Action notes: anyOf: - type: string - type: 'null' title: Notes type: object required: - action title: ReviewAction ReviewCommentRequest: properties: comment: type: string maxLength: 4000 minLength: 1 title: Comment type: object required: - comment title: ReviewCommentRequest ReviewEvidenceRequest: properties: decision: type: string enum: - accepted - rejected title: Decision reviewer: anyOf: - type: string - type: 'null' title: Reviewer type: object required: - decision title: ReviewEvidenceRequest RiskProfileOut: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id user_id: anyOf: - type: string format: uuid - type: 'null' title: User Id external_user_ref: anyOf: - type: string - type: 'null' title: External User Ref risk_score: type: number title: Risk Score risk_tier: type: string title: Risk Tier failed_auth_24h: type: integer title: Failed Auth 24H off_hours_events_7d: type: integer title: Off Hours Events 7D data_staging_score: type: number title: Data Staging Score peer_anomaly_score: type: number title: Peer Anomaly Score privilege_delta: type: integer title: Privilege Delta is_watchlisted: type: boolean title: Is Watchlisted watchlist_reason: anyOf: - type: string - type: 'null' title: Watchlist Reason last_evaluated_at: type: string title: Last Evaluated At updated_at: type: string title: Updated At type: object required: - id - tenant_id - user_id - external_user_ref - risk_score - risk_tier - failed_auth_24h - off_hours_events_7d - data_staging_score - peer_anomaly_score - privilege_delta - is_watchlisted - watchlist_reason - last_evaluated_at - updated_at title: RiskProfileOut RoleIn: properties: name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description permission_ids: items: type: string format: uuid type: array title: Permission Ids default: [] type: object required: - name title: RoleIn RoleOut: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description is_system: type: boolean title: Is System permissions: items: $ref: '#/components/schemas/PermissionOut' type: array title: Permissions default: [] type: object required: - id - tenant_id - name - description - is_system title: RoleOut RoleUpdate: properties: name: anyOf: - type: string - type: 'null' title: Name description: anyOf: - type: string - type: 'null' title: Description permission_ids: anyOf: - items: type: string format: uuid type: array - type: 'null' title: Permission Ids type: object title: RoleUpdate RuleActionWire: properties: set_severity: anyOf: - type: string - type: 'null' title: Set Severity route_to: anyOf: - type: string - type: 'null' title: Route To tag: anyOf: - type: string - type: 'null' title: Tag suppress: type: boolean title: Suppress default: false type: object title: RuleActionWire RuleConditionWire: properties: field: anyOf: - type: string - type: 'null' title: Field op: anyOf: - type: string - type: 'null' title: Op value: title: Value logical: anyOf: - type: string - type: 'null' title: Logical children: items: $ref: '#/components/schemas/RuleConditionWire' type: array title: Children type: object title: RuleConditionWire description: Mirror of :class:`RuleCondition` for the wire / OpenAPI shape. RuleOverrideCreate: properties: child_tenant_id: type: string format: uuid title: Child Tenant Id rule_id: type: string format: uuid title: Rule Id action: type: string title: Action note: anyOf: - type: string - type: 'null' title: Note severity_override: anyOf: - type: string - type: 'null' title: Severity Override parameter_overrides: additionalProperties: true type: object title: Parameter Overrides default: {} type: object required: - child_tenant_id - rule_id - action title: RuleOverrideCreate RuleOverrideOut: properties: id: type: string format: uuid title: Id parent_tenant_id: type: string format: uuid title: Parent Tenant Id child_tenant_id: type: string format: uuid title: Child Tenant Id rule_id: type: string format: uuid title: Rule Id action: type: string title: Action note: anyOf: - type: string - type: 'null' title: Note severity_override: anyOf: - type: string - type: 'null' title: Severity Override parameter_overrides: additionalProperties: true type: object title: Parameter Overrides created_at: type: string title: Created At type: object required: - id - parent_tenant_id - child_tenant_id - rule_id - action - note - severity_override - parameter_overrides - created_at title: RuleOverrideOut RulePackCreate: properties: name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description category: anyOf: - type: string - type: 'null' title: Category is_default: type: boolean title: Is Default default: false type: object required: - name title: RulePackCreate RulePackOut: properties: id: type: string format: uuid title: Id name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description category: anyOf: - type: string - type: 'null' title: Category is_default: type: boolean title: Is Default created_at: type: string title: Created At updated_at: type: string title: Updated At type: object required: - id - name - description - category - is_default - created_at - updated_at title: RulePackOut RulePackRuleAdd: properties: rule_id: type: string format: uuid title: Rule Id type: object required: - rule_id title: RulePackRuleAdd RulePackUpdate: properties: name: anyOf: - type: string - type: 'null' title: Name description: anyOf: - type: string - type: 'null' title: Description category: anyOf: - type: string - type: 'null' title: Category is_default: anyOf: - type: boolean - type: 'null' title: Is Default type: object title: RulePackUpdate RuleWire: properties: id: type: string title: Id description: type: string title: Description default: '' enabled: type: boolean title: Enabled default: true priority: type: integer title: Priority default: 100 when: $ref: '#/components/schemas/RuleConditionWire' then: $ref: '#/components/schemas/RuleActionWire' type: object required: - id - when - then title: RuleWire RulesEnvelope: properties: tenant_id: type: string title: Tenant Id version: type: integer title: Version yaml: type: string title: Yaml rules: items: $ref: '#/components/schemas/RuleWire' type: array title: Rules enabled: type: boolean title: Enabled updated_at: type: string title: Updated At type: object required: - tenant_id - version - yaml - rules - enabled - updated_at title: RulesEnvelope description: 'Response payload for ``GET /rules``. The editor needs *both* the YAML source (so Monaco can show formatting + comments) and the parsed view (so the rule-builder side-panel can render structured forms). ``version`` is the engine snapshot version the parsed view came from — a monotonic integer the UI uses to detect "someone else saved while I was editing".' RunDetail: properties: id: type: string format: uuid title: Id case_id: type: string title: Case Id status: type: string title: Status model_used: anyOf: - type: string - type: 'null' title: Model Used iterations: type: integer title: Iterations total_tokens: type: integer title: Total Tokens total_cost_usd: type: number title: Total Cost Usd started_at: type: string format: date-time title: Started At completed_at: anyOf: - type: string format: date-time - type: 'null' title: Completed At error: anyOf: - type: string - type: 'null' title: Error alert_summary: anyOf: - type: string - type: 'null' title: Alert Summary event_count: type: integer title: Event Count artifact_count: type: integer title: Artifact Count model_costs: items: $ref: '#/components/schemas/ModelCostBreakdown' type: array title: Model Costs type: object required: - id - case_id - status - model_used - iterations - total_tokens - total_cost_usd - started_at - completed_at - error - alert_summary - event_count - artifact_count - model_costs title: RunDetail description: Full run view including counts of attached children. RunEvalRequest: properties: use_active_baseline: type: boolean title: Use Active Baseline description: If true (default), the most recent active MITRE accuracy baseline is materialised to a temp file and passed to run_evals.py via --baseline so the runner can compute baseline_compare in-band. default: true max_regression_pp: type: number maximum: 50.0 minimum: 0.0 title: Max Regression Pp description: Allowed MITRE accuracy regression vs the active baseline, in percentage points. Forwarded to run_evals.py. Hard-capped at 50 to keep the regression gate meaningful. default: 1.0 timeout_seconds: type: integer maximum: 600.0 minimum: 10.0 title: Timeout Seconds description: Hard timeout for the eval subprocess. Capped at 10 minutes — the synthetic benchmark completes in under 60s on commodity hardware so anything longer is almost certainly a stuck process. default: 180 type: object title: RunEvalRequest description: 'Trigger a local run of the offline eval harness. The runner is `scripts/run_evals.py`. It is fully offline and deterministic against the 200-incident synthetic benchmark, so this endpoint can be safely called from the rule editor on every "Propose for review" action.' RunEvalResponse: properties: report: additionalProperties: true type: object title: Report exit_code: type: integer title: Exit Code duration_seconds: type: number title: Duration Seconds ran_at: type: string format: date-time title: Ran At script: type: string title: Script type: object required: - report - exit_code - duration_seconds - ran_at - script title: RunEvalResponse description: Wraps the JSON report emitted by `run_evals.py`. RunHuntRequest: properties: platform: type: string enum: - esql - spl - kql title: Platform default: esql type: object title: RunHuntRequest RunRequest: properties: payload: additionalProperties: true type: object title: Payload default: {} context: additionalProperties: true type: object title: Context default: {} type: object title: RunRequest RunResponse: properties: plugin_id: type: string title: Plugin Id result: additionalProperties: true type: object title: Result type: object required: - plugin_id - result title: RunResponse RunSavedHuntResponse: properties: id: type: string title: Id name: type: string title: Name nl_query: type: string title: Nl Query translated_query: $ref: '#/components/schemas/TranslatedQueryEnvelope' last_run_at: type: string title: Last Run At type: object required: - id - name - nl_query - translated_query - last_run_at title: RunSavedHuntResponse description: 'Synchronous run result returned by ``POST /saved-hunts/{id}/run``. The endpoint *does not* execute the underlying ES|QL — that path is the job of :mod:`app.api.v1.endpoints.nl_query` (``/nl-query/execute``) and requires a configured Elasticsearch URL. The ``/run`` endpoint here only re-translates and stamps ``last_run_at`` so the UI can show "last run just now" and so the scheduler treats a manual run as resetting cadence.' RunSummary: properties: id: type: string format: uuid title: Id case_id: type: string title: Case Id status: type: string title: Status model_used: anyOf: - type: string - type: 'null' title: Model Used iterations: type: integer title: Iterations total_tokens: type: integer title: Total Tokens total_cost_usd: type: number title: Total Cost Usd started_at: type: string format: date-time title: Started At completed_at: anyOf: - type: string format: date-time - type: 'null' title: Completed At error: anyOf: - type: string - type: 'null' title: Error type: object required: - id - case_id - status - model_used - iterations - total_tokens - total_cost_usd - started_at - completed_at - error title: RunSummary description: Compact view of a run for list endpoints. SLAConfigOut: properties: id: type: string format: uuid title: Id severity: type: string title: Severity mttd_target: type: integer title: Mttd Target mttr_target: type: integer title: Mttr Target mttc_target: type: integer title: Mttc Target updated_at: type: string format: date-time title: Updated At type: object required: - id - severity - mttd_target - mttr_target - mttc_target - updated_at title: SLAConfigOut SLAConfigUpdate: properties: mttd_target: type: integer maximum: 10080.0 minimum: 1.0 title: Mttd Target description: Minutes mttr_target: type: integer maximum: 10080.0 minimum: 1.0 title: Mttr Target description: Minutes mttc_target: type: integer maximum: 10080.0 minimum: 1.0 title: Mttc Target description: Minutes type: object required: - mttd_target - mttr_target - mttc_target title: SLAConfigUpdate SLAEventCreate: properties: alert_id: type: string format: uuid title: Alert Id severity: type: string title: Severity event_type: type: string title: Event Type occurred_at: anyOf: - type: string format: date-time - type: 'null' title: Occurred At metadata: additionalProperties: true type: object title: Metadata type: object required: - alert_id - severity - event_type title: SLAEventCreate SLAEventOut: properties: id: type: string format: uuid title: Id alert_id: type: string format: uuid title: Alert Id severity: type: string title: Severity event_type: type: string title: Event Type occurred_at: type: string format: date-time title: Occurred At metadata: additionalProperties: true type: object title: Metadata type: object required: - id - alert_id - severity - event_type - occurred_at - metadata title: SLAEventOut SOCInsightsResponse: properties: window: type: string enum: - 24h - 7d - 30d title: Window generated_at: type: string format: date-time title: Generated At tenant_id: type: string format: uuid title: Tenant Id tiles: items: $ref: '#/components/schemas/InsightTile' type: array title: Tiles manual_investigation_minutes: type: integer title: Manual Investigation Minutes default: 45 type: object required: - window - generated_at - tenant_id - tiles title: SOCInsightsResponse description: Aggregated SOC insights payload. SOCKpis: properties: mttd_hours: type: number title: Mttd Hours mttr_hours: type: number title: Mttr Hours mttc_hours: type: number title: Mttc Hours false_positive_rate: type: number title: False Positive Rate escalation_rate: type: number title: Escalation Rate alert_volume_7d: type: integer title: Alert Volume 7D cases_opened_7d: type: integer title: Cases Opened 7D cases_closed_7d: type: integer title: Cases Closed 7D analyst_overrides_7d: type: integer title: Analyst Overrides 7D type: object required: - mttd_hours - mttr_hours - mttc_hours - false_positive_rate - escalation_rate - alert_volume_7d - cases_opened_7d - cases_closed_7d - analyst_overrides_7d title: SOCKpis SOCMetrics: properties: kpis: $ref: '#/components/schemas/SOCKpis' attack_heatmap: items: $ref: '#/components/schemas/AttackHeatmapCell' type: array title: Attack Heatmap calibration_curve: items: $ref: '#/components/schemas/CalibrationBucket' type: array title: Calibration Curve type: object required: - kpis - attack_heatmap - calibration_curve title: SOCMetrics STIXBundle: properties: type: type: string title: Type default: bundle id: type: string title: Id spec_version: type: string title: Spec Version default: '2.1' created: type: string title: Created objects: items: additionalProperties: true type: object type: array title: Objects type: object required: - id - created - objects title: STIXBundle STIXBundleCreate: properties: objects: items: additionalProperties: true type: object type: array title: Objects type: object required: - objects title: STIXBundleCreate STIXBundleWithPush: properties: type: type: string title: Type default: bundle id: type: string title: Id spec_version: type: string title: Spec Version default: '2.1' created: type: string title: Created objects: items: additionalProperties: true type: object type: array title: Objects misp: anyOf: - $ref: '#/components/schemas/MispPushResult' - type: 'null' type: object required: - id - created - objects title: STIXBundleWithPush STIXIndicator: properties: type: type: string title: Type default: indicator spec_version: type: string title: Spec Version default: '2.1' id: type: string title: Id created: type: string title: Created modified: type: string title: Modified name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description indicator_types: items: type: string type: array title: Indicator Types default: [] pattern: type: string title: Pattern pattern_type: type: string title: Pattern Type default: stix valid_from: type: string title: Valid From valid_until: anyOf: - type: string - type: 'null' title: Valid Until confidence: anyOf: - type: integer maximum: 100.0 minimum: 0.0 - type: 'null' title: Confidence labels: items: type: string type: array title: Labels default: [] type: object required: - id - created - modified - name - pattern - valid_from title: STIXIndicator STIXIndicatorCreate: properties: name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description indicator_types: items: type: string type: array title: Indicator Types default: [] pattern: type: string title: Pattern pattern_type: type: string title: Pattern Type default: stix valid_from: anyOf: - type: string - type: 'null' title: Valid From valid_until: anyOf: - type: string - type: 'null' title: Valid Until confidence: anyOf: - type: integer maximum: 100.0 minimum: 0.0 - type: 'null' title: Confidence labels: items: type: string type: array title: Labels default: [] type: object required: - name - pattern title: STIXIndicatorCreate STIXIndicatorWithPush: properties: type: type: string title: Type default: indicator spec_version: type: string title: Spec Version default: '2.1' id: type: string title: Id created: type: string title: Created modified: type: string title: Modified name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description indicator_types: items: type: string type: array title: Indicator Types default: [] pattern: type: string title: Pattern pattern_type: type: string title: Pattern Type default: stix valid_from: type: string title: Valid From valid_until: anyOf: - type: string - type: 'null' title: Valid Until confidence: anyOf: - type: integer maximum: 100.0 minimum: 0.0 - type: 'null' title: Confidence labels: items: type: string type: array title: Labels default: [] misp: anyOf: - $ref: '#/components/schemas/MispPushResult' - type: 'null' type: object required: - id - created - modified - name - pattern - valid_from title: STIXIndicatorWithPush SavedHuntModel: properties: id: type: string title: Id name: type: string title: Name nl_query: type: string title: Nl Query translated_query: $ref: '#/components/schemas/TranslatedQueryEnvelope' language: type: string enum: - esql - kql - spl title: Language schedule: anyOf: - type: string - type: 'null' title: Schedule last_run_at: anyOf: - type: string - type: 'null' title: Last Run At created_at: type: string title: Created At updated_at: type: string title: Updated At created_by: anyOf: - type: string - type: 'null' title: Created By type: object required: - id - name - nl_query - translated_query - language - created_at - updated_at title: SavedHuntModel description: Wire format for a saved hunt row. SavedViewModel: properties: id: type: string title: Id view_type: type: string title: View Type name: type: string title: Name filters: additionalProperties: true type: object title: Filters columns: anyOf: - items: {} type: array - additionalProperties: true type: object - type: 'null' title: Columns is_default: type: boolean title: Is Default default: false created_at: type: string title: Created At updated_at: type: string title: Updated At type: object required: - id - view_type - name - created_at - updated_at title: SavedViewModel description: Wire format for a saved view row. ScanRequest: properties: tenant_id: type: string format: uuid title: Tenant Id org_query: anyOf: - type: string - type: 'null' title: Org Query ip_targets: items: type: string type: array title: Ip Targets default: [] asset_type: anyOf: - $ref: '#/components/schemas/ExternalAssetType' - type: 'null' type: object required: - tenant_id title: ScanRequest ScanRunOut: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id cloud_provider: type: string title: Cloud Provider cloud_account: anyOf: - type: string - type: 'null' title: Cloud Account started_at: type: string title: Started At completed_at: anyOf: - type: string - type: 'null' title: Completed At status: type: string title: Status findings_total: type: integer title: Findings Total findings_new: type: integer title: Findings New findings_closed: type: integer title: Findings Closed error_message: anyOf: - type: string - type: 'null' title: Error Message type: object required: - id - tenant_id - cloud_provider - cloud_account - started_at - completed_at - status - findings_total - findings_new - findings_closed - error_message title: ScanRunOut ShiftAnalyst: properties: id: type: string title: Id name: type: string title: Name role: type: string title: Role type: object required: - id - name - role title: ShiftAnalyst ShiftCreate: properties: name: type: string maxLength: 120 minLength: 1 title: Name analysts: items: type: string type: array title: Analysts description: Analyst user IDs lead_id: anyOf: - type: string - type: 'null' title: Lead Id type: object required: - name title: ShiftCreate ShiftSummary: properties: id: type: string title: Id name: type: string title: Name started_at: type: string title: Started At ended_at: anyOf: - type: string - type: 'null' title: Ended At status: type: string title: Status lead: $ref: '#/components/schemas/ShiftAnalyst' analyst_count: type: integer title: Analyst Count alerts_handled: type: integer title: Alerts Handled escalations: type: integer title: Escalations handoff_notes: anyOf: - type: string - type: 'null' title: Handoff Notes type: object required: - id - name - started_at - status - lead - analyst_count - alerts_handled - escalations title: ShiftSummary SourceStat: properties: name: type: string title: Name count: type: integer title: Count status: type: string title: Status type: object required: - name - count - status title: SourceStat SourceThreat: properties: source: type: string title: Source count: type: integer title: Count type: object required: - source - count title: SourceThreat SourceVerdict: properties: connector_id: type: string format: uuid title: Connector Id connector_name: type: string title: Connector Name connector_type: type: string title: Connector Type status: type: string title: Status row_count: type: integer title: Row Count default: 0 duration_ms: type: integer title: Duration Ms default: 0 error: anyOf: - type: string - type: 'null' title: Error type: object required: - connector_id - connector_name - connector_type - status title: SourceVerdict description: "Per-backend outcome for a federated call.\n\n``status`` is one\ \ of:\n * ``ok`` — backend returned rows (possibly zero).\n * ``error``\ \ — backend raised something we caught; ``error`` field\n carries the human\ \ message. Other backends may still have\n succeeded.\n * ``unsupported``\ \ — connector type doesn't speak federated search\n (kept for forward-compat;\ \ today we pre-filter so this is rare)." SubmissionResponse: properties: id: type: string format: uuid title: Id artifact_kind: type: string title: Artifact Kind sender: anyOf: - type: string - type: 'null' title: Sender subject: anyOf: - type: string - type: 'null' title: Subject urls: items: type: string type: array title: Urls verdict: type: string title: Verdict confidence: anyOf: - type: number - type: 'null' title: Confidence indicators: items: additionalProperties: true type: object type: array title: Indicators mitre_technique: anyOf: - type: string - type: 'null' title: Mitre Technique case_id: anyOf: - type: string format: uuid - type: 'null' title: Case Id submitted_at: type: string format: date-time title: Submitted At triaged_at: anyOf: - type: string format: date-time - type: 'null' title: Triaged At type: object required: - id - artifact_kind - sender - subject - urls - verdict - confidence - indicators - mitre_technique - case_id - submitted_at - triaged_at title: SubmissionResponse SubmitRequest: properties: artifact_kind: type: string enum: - email - url - attachment - domain title: Artifact Kind default: email raw_content: anyOf: - type: string - type: 'null' title: Raw Content description: Raw email source or URL to analyse. sender: anyOf: - type: string - type: 'null' title: Sender subject: anyOf: - type: string - type: 'null' title: Subject urls: items: type: string type: array title: Urls type: object title: SubmitRequest SuggestRequest: properties: alert_id: type: string format: uuid title: Alert Id description: ID of the FP-flagged alert. analyst_note: anyOf: - type: string - type: 'null' title: Analyst Note description: Free-text note explaining why this is a FP. type: object required: - alert_id title: SuggestRequest SuggestionListResponse: properties: suggestions: items: $ref: '#/components/schemas/SuggestionResponse' type: array title: Suggestions total: type: integer title: Total type: object required: - suggestions - total title: SuggestionListResponse SuggestionResponse: properties: suggestion_id: type: string format: uuid title: Suggestion Id alert_id: type: string format: uuid title: Alert Id base_rule_id: anyOf: - type: string format: uuid - type: 'null' title: Base Rule Id draft_rule_name: type: string title: Draft Rule Name draft_sigma_yaml: type: string title: Draft Sigma Yaml rationale: type: string title: Rationale proposal_id: anyOf: - type: string format: uuid - type: 'null' title: Proposal Id created_at: type: string format: date-time title: Created At type: object required: - suggestion_id - alert_id - base_rule_id - draft_rule_name - draft_sigma_yaml - rationale - proposal_id - created_at title: SuggestionResponse SuppressRequest: properties: reason: type: string title: Reason type: object required: - reason title: SuppressRequest TAXIICollection: properties: id: type: string title: Id title: type: string title: Title description: type: string title: Description can_read: type: boolean title: Can Read default: true can_write: type: boolean title: Can Write default: false media_types: items: type: string type: array title: Media Types default: - application/stix+json;version=2.1 type: object required: - id - title - description title: TAXIICollection TAXIICollectionListResponse: properties: items: items: $ref: '#/components/schemas/TAXIICollection' type: array title: Items total: type: integer title: Total type: object required: - items - total title: TAXIICollectionListResponse TacticConfidence: properties: tactic: type: string title: Tactic rules: type: integer title: Rules activeRules: type: integer title: Activerules avgConfidence: type: number title: Avgconfidence avgConfidenceActive: type: number title: Avgconfidenceactive type: object required: - tactic - rules - activeRules - avgConfidence - avgConfidenceActive title: TacticConfidence description: 'Average rule confidence within one MITRE tactic. Useful for the "where is my coverage weakest?" question — analysts plot tactics as bars and immediately see that, e.g. *exfiltration* averages 38/100 while *execution* averages 78/100.' TaskResponse: properties: id: type: string title: Id title: type: string title: Title status: type: string enum: - todo - in_progress - done title: Status assignee: anyOf: - type: string - type: 'null' title: Assignee dueAt: anyOf: - type: string format: date-time - type: 'null' title: Dueat createdAt: type: string format: date-time title: Createdat type: object required: - id - title - status - createdAt title: TaskResponse TemplateCreate: properties: name: type: string title: Name report_type: type: string title: Report Type cron_schedule: anyOf: - type: string - type: 'null' title: Cron Schedule timezone: type: string title: Timezone default: UTC sections: items: additionalProperties: true type: object type: array title: Sections recipients: anyOf: - items: type: string type: array - type: 'null' title: Recipients output_format: type: string title: Output Format default: pdf type: object required: - name - report_type title: TemplateCreate TemplateOut: properties: name: type: string title: Name report_type: type: string title: Report Type cron_schedule: anyOf: - type: string - type: 'null' title: Cron Schedule timezone: type: string title: Timezone default: UTC sections: items: additionalProperties: true type: object type: array title: Sections recipients: anyOf: - items: type: string type: array - type: 'null' title: Recipients output_format: type: string title: Output Format default: pdf id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id is_enabled: type: boolean title: Is Enabled last_run_at: anyOf: - type: string - type: 'null' title: Last Run At created_at: type: string title: Created At updated_at: type: string title: Updated At type: object required: - name - report_type - id - tenant_id - is_enabled - created_at - updated_at title: TemplateOut TenantHeaderResponse: properties: id: type: string format: uuid title: Id name: type: string title: Name mssp_role: anyOf: - type: string - type: 'null' title: Mssp Role parent_tenant_id: anyOf: - type: string format: uuid - type: 'null' title: Parent Tenant Id type: object required: - id - name - mssp_role - parent_tenant_id title: TenantHeaderResponse description: 'Minimal tenant identity payload — safe for *any* authenticated user. Used by the SOC console TopBar to render the tenant switcher and role badge (Workstream 5). Intentionally excludes `plan`, `settings`, and `limits` so it does not leak privileged config to viewer/analyst roles.' TenantListEntry: properties: id: type: string title: Id name: type: string title: Name slug: type: string title: Slug plan: type: string title: Plan is_active: type: boolean title: Is Active is_managed: type: boolean title: Is Managed provisioned_from_waitlist_id: anyOf: - type: string - type: 'null' title: Provisioned From Waitlist Id provisioned_at: anyOf: - type: string - type: 'null' title: Provisioned At created_at: type: string title: Created At type: object required: - id - name - slug - plan - is_active - is_managed - provisioned_from_waitlist_id - provisioned_at - created_at title: TenantListEntry TenantListResponse: properties: tenants: items: $ref: '#/components/schemas/TenantListEntry' type: array title: Tenants total: type: integer title: Total type: object required: - tenants - total title: TenantListResponse TenantNoteCreate: properties: child_id: type: string format: uuid title: Child Id body: type: string title: Body type: object required: - child_id - body title: TenantNoteCreate TenantNoteOut: properties: child_id: type: string format: uuid title: Child Id body: type: string title: Body id: type: string format: uuid title: Id parent_id: type: string format: uuid title: Parent Id author_id: anyOf: - type: string format: uuid - type: 'null' title: Author Id created_at: type: string title: Created At type: object required: - child_id - body - id - parent_id - author_id - created_at title: TenantNoteOut TenantProvisionRequest: properties: waitlist_entry_id: type: string format: uuid title: Waitlist Entry Id seed_demo: type: boolean title: Seed Demo default: true invite_base_url: anyOf: - type: string maxLength: 512 - type: 'null' title: Invite Base Url type: object required: - waitlist_entry_id title: TenantProvisionRequest description: 'Body of the provision POST. ``waitlist_entry_id`` is the only required field. The optional ``seed_demo`` flag lets the operator turn off the starter dataset for tenants where the customer wants a clean slate.' TenantProvisionResponse: properties: tenant_id: type: string title: Tenant Id tenant_slug: type: string title: Tenant Slug tenant_name: type: string title: Tenant Name waitlist_entry_id: type: string title: Waitlist Entry Id admin_user: $ref: '#/components/schemas/InitialAdminUserWire' admin_invite: $ref: '#/components/schemas/AdminInviteWire' demo_seeded: type: boolean title: Demo Seeded aisoc_credential_key_fingerprint: type: string title: Aisoc Credential Key Fingerprint type: object required: - tenant_id - tenant_slug - tenant_name - waitlist_entry_id - admin_user - admin_invite - demo_seeded - aisoc_credential_key_fingerprint title: TenantProvisionResponse description: 'JSON projection of :class:`ProvisionResult`. ``aisoc_credential_key_fingerprint`` is surfaced so the support UI can confirm at a glance which key the tenant is on. The *plaintext* key is never returned; it''s only readable from the process environment where it was minted.' TenantResponse: properties: id: type: string format: uuid title: Id name: type: string title: Name slug: type: string title: Slug plan: type: string title: Plan is_active: type: boolean title: Is Active settings: additionalProperties: true type: object title: Settings limits: additionalProperties: true type: object title: Limits mssp_role: anyOf: - type: string - type: 'null' title: Mssp Role parent_tenant_id: anyOf: - type: string format: uuid - type: 'null' title: Parent Tenant Id created_at: type: string format: date-time title: Created At type: object required: - id - name - slug - plan - is_active - settings - limits - created_at title: TenantResponse TestBody: properties: language: type: string title: Language body: type: string title: Body sample: anyOf: - type: string - type: 'null' title: Sample type: object required: - language - body title: TestBody TestConnectionRequest: properties: connector_type: type: string maxLength: 100 minLength: 1 title: Connector Type auth_config: additionalProperties: true type: object title: Auth Config connector_config: additionalProperties: true type: object title: Connector Config type: object required: - connector_type title: TestConnectionRequest description: 'Inline credential-test payload used by the wizard *before* saving. The wizard collects credentials in-browser, calls this endpoint, and only persists the connector if the test succeeds. We intentionally do *not* let the wizard test against an existing instance — that''s a separate path (:func:`test_existing_connector`) that decrypts the stored creds first.' TestResponse: properties: matches: type: integer title: Matches preview: items: $ref: '#/components/schemas/HuntPreviewItem' type: array title: Preview type: object required: - matches - preview title: TestResponse ThreatActorCreate: properties: name: type: string title: Name aliases: anyOf: - items: type: string type: array - type: 'null' title: Aliases motivation: anyOf: - type: string - type: 'null' title: Motivation sophistication: anyOf: - type: string - type: 'null' title: Sophistication country_of_origin: anyOf: - type: string - type: 'null' title: Country Of Origin target_sectors: anyOf: - items: type: string type: array - type: 'null' title: Target Sectors ttps: anyOf: - items: type: string type: array - type: 'null' title: Ttps description: anyOf: - type: string - type: 'null' title: Description first_observed: anyOf: - type: string format: date-time - type: 'null' title: First Observed last_activity: anyOf: - type: string format: date-time - type: 'null' title: Last Activity context: additionalProperties: true type: object title: Context type: object required: - name title: ThreatActorCreate ThreatActorOut: properties: name: type: string title: Name aliases: anyOf: - items: type: string type: array - type: 'null' title: Aliases motivation: anyOf: - type: string - type: 'null' title: Motivation sophistication: anyOf: - type: string - type: 'null' title: Sophistication country_of_origin: anyOf: - type: string - type: 'null' title: Country Of Origin target_sectors: anyOf: - items: type: string type: array - type: 'null' title: Target Sectors ttps: anyOf: - items: type: string type: array - type: 'null' title: Ttps description: anyOf: - type: string - type: 'null' title: Description first_observed: anyOf: - type: string format: date-time - type: 'null' title: First Observed last_activity: anyOf: - type: string format: date-time - type: 'null' title: Last Activity context: additionalProperties: true type: object title: Context id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id is_active: type: boolean title: Is Active created_at: type: string title: Created At type: object required: - name - id - tenant_id - is_active - created_at title: ThreatActorOut ThresholdTriple: properties: auto: type: number maximum: 1.0 minimum: 0.0 title: Auto review: type: number maximum: 1.0 minimum: 0.0 title: Review escalation: type: number maximum: 1.0 minimum: 0.0 title: Escalation type: object required: - auto - review - escalation title: ThresholdTriple description: 'Three confidence cutoffs for one action. Invariant: ``escalation <= review <= auto`` and all are in ``[0.0, 1.0]``.' ThresholdUpdateRequest: properties: auto: type: number maximum: 1.0 minimum: 0.0 title: Auto review: type: number maximum: 1.0 minimum: 0.0 title: Review escalation: type: number maximum: 1.0 minimum: 0.0 title: Escalation reason: anyOf: - type: string maxLength: 500 - type: 'null' title: Reason description: Free-text justification — surfaced in the audit log. type: object required: - auto - review - escalation title: ThresholdUpdateRequest ThresholdUpdateResponse: properties: action: type: string title: Action thresholds: $ref: '#/components/schemas/ThresholdTriple' updated_at: type: string title: Updated At updated_by: type: string title: Updated By type: object required: - action - thresholds - updated_at - updated_by title: ThresholdUpdateResponse TimelineDecision: properties: reason: anyOf: - type: string - type: 'null' title: Reason confidence: anyOf: - type: number - type: 'null' title: Confidence next_phase: anyOf: - type: string - type: 'null' title: Next Phase tool_name: anyOf: - type: string - type: 'null' title: Tool Name tool_args: anyOf: - additionalProperties: true type: object - type: 'null' title: Tool Args tool_result_summary: anyOf: - type: string - type: 'null' title: Tool Result Summary type: object required: - reason - confidence - next_phase - tool_name - tool_args - tool_result_summary title: TimelineDecision description: Agent decision provenance annotation for a single timeline node. TimelineNode: properties: seq: type: integer title: Seq ts: type: string format: date-time title: Ts kind: type: string title: Kind agent: type: string title: Agent summary: type: string title: Summary duration_ms: type: integer title: Duration Ms decision: anyOf: - $ref: '#/components/schemas/TimelineDecision' - type: 'null' has_artifact: type: boolean title: Has Artifact diff_vs_prev_attempt: anyOf: - type: string - type: 'null' title: Diff Vs Prev Attempt type: object required: - seq - ts - kind - agent - summary - duration_ms - decision - has_artifact - diff_vs_prev_attempt title: TimelineNode description: One node in the scrubbable investigation timeline. TokenResponse: properties: access_token: type: string title: Access Token refresh_token: type: string title: Refresh Token token_type: type: string title: Token Type default: bearer expires_in: type: integer title: Expires In default: 1800 type: object required: - access_token - refresh_token title: TokenResponse TopCostCase: properties: case_id: type: string title: Case Id runs: type: integer title: Runs total_cost_usd: type: number title: Total Cost Usd total_tokens: type: integer title: Total Tokens type: object required: - case_id - runs - total_cost_usd - total_tokens title: TopCostCase description: 'The most expensive cases over the window. Top-cost playbooks ≈ top-cost cases in the AiSOC data model: a case is the unit of work an analyst (or playbook) drives, and ``investigation_runs.case_id`` is the only stable join we can make between LLM cost and "what was this money spent on?".' TranslateRequest: properties: source_format: type: string enum: - sigma - spl - kql - esql - yara_l2 - udm title: Source Format description: Format of the input rule. source_rule: type: string minLength: 5 title: Source Rule description: The raw rule text to translate. target_formats: items: type: string enum: - sigma - spl - kql - esql - yara_l2 - udm type: array title: Target Formats description: Output formats to produce. default: - sigma - spl - kql - esql type: object required: - source_format - source_rule title: TranslateRequest TranslateResponse: properties: source_format: type: string enum: - sigma - spl - kql - esql - yara_l2 - udm title: Source Format results: items: $ref: '#/components/schemas/TranslationResult' type: array title: Results warnings: items: type: string type: array title: Warnings default: [] type: object required: - source_format - results title: TranslateResponse TranslatedQueryEnvelope: properties: esql: type: string title: Esql default: '' kql: type: string title: Kql default: '' spl: type: string title: Spl default: '' explanation: type: string title: Explanation default: '' type: object title: TranslatedQueryEnvelope description: 'Translator output stored alongside the NL question. Mirrors :class:`services.agents.app.nl_query.translator.TranslatedQuery` but without the ``intents`` IR (which is internal to the translator).' TranslationResult: properties: format: type: string enum: - sigma - spl - kql - esql - yara_l2 - udm title: Format label: type: string title: Label rule: type: string title: Rule notes: anyOf: - type: string - type: 'null' title: Notes type: object required: - format - label - rule title: TranslationResult TrendPoint: properties: timestamp: type: string title: Timestamp count: type: integer title: Count severity: type: string title: Severity type: object required: - timestamp - count - severity title: TrendPoint TroubleshootRequest: properties: connector_type: type: string maxLength: 100 minLength: 1 title: Connector Type error: type: string maxLength: 4000 minLength: 1 title: Error auth_config_keys: items: type: string type: array title: Auth Config Keys description: Names of fields the operator filled in. Values are intentionally *not* sent — the troubleshooter doesn't need plaintext credentials to diagnose '401 Unauthorized'. type: object required: - connector_type - error title: TroubleshootRequest description: AI-troubleshooter input from the wizard's failure UX. TroubleshootResponse: properties: likely_cause: type: string title: Likely Cause fix_steps: items: type: string type: array title: Fix Steps doc_link: anyOf: - type: string - type: 'null' title: Doc Link type: object required: - likely_cause - fix_steps title: TroubleshootResponse description: Structured guidance the wizard renders next to a failed test. TuningEntry: properties: rule_id: type: string title: Rule Id name: type: string title: Name description: anyOf: - type: string - type: 'null' title: Description category: type: string title: Category severity: type: string title: Severity status: type: string title: Status enabled: type: boolean title: Enabled confidence: type: integer title: Confidence fp_rate: type: number title: Fp Rate total_hits: type: integer title: Total Hits last_triggered_at: anyOf: - type: string - type: 'null' title: Last Triggered At tags: items: type: string type: array title: Tags mitre_tactics: items: type: string type: array title: Mitre Tactics mitre_techniques: items: type: string type: array title: Mitre Techniques version: type: integer title: Version updated_at: type: string title: Updated At suggestion: type: string enum: - disable - add_suppression - raise_threshold - tune_confidence - review_stale - healthy title: Suggestion score: type: integer title: Score reasons: items: type: string type: array title: Reasons auto_tune: type: boolean title: Auto Tune default: false dismissed_at: anyOf: - type: string - type: 'null' title: Dismissed At last_action: anyOf: - type: string - type: 'null' title: Last Action last_action_at: anyOf: - type: string - type: 'null' title: Last Action At type: object required: - rule_id - name - category - severity - status - enabled - confidence - fp_rate - total_hits - version - updated_at - suggestion - score title: TuningEntry description: One row in the tuning workbench — what an analyst sees. TuningFilters: properties: severity: anyOf: - type: string - type: 'null' title: Severity suggestion: anyOf: - type: string - type: 'null' title: Suggestion search: anyOf: - type: string - type: 'null' title: Search enabled_only: type: boolean title: Enabled Only default: false include_dismissed: type: boolean title: Include Dismissed default: false page: type: integer title: Page default: 1 page_size: type: integer title: Page Size default: 50 type: object title: TuningFilters description: Echo of the filters that built this response (handy for the UI). TuningResponse: properties: entries: items: $ref: '#/components/schemas/TuningEntry' type: array title: Entries summary: $ref: '#/components/schemas/TuningSummary' filters: $ref: '#/components/schemas/TuningFilters' total: type: integer title: Total generated_at: type: string title: Generated At type: object required: - entries - summary - filters - total - generated_at title: TuningResponse description: Wire shape for ``GET /detection/tuning``. TuningSummary: properties: total_rules: type: integer title: Total Rules actionable: type: integer title: Actionable healthy: type: integer title: Healthy disable_count: type: integer title: Disable Count default: 0 add_suppression_count: type: integer title: Add Suppression Count default: 0 raise_threshold_count: type: integer title: Raise Threshold Count default: 0 tune_confidence_count: type: integer title: Tune Confidence Count default: 0 review_stale_count: type: integer title: Review Stale Count default: 0 auto_tune_enabled: type: integer title: Auto Tune Enabled default: 0 average_fp_rate: type: number title: Average Fp Rate default: 0.0 high_fp_count: type: integer title: High Fp Count default: 0 type: object required: - total_rules - actionable - healthy title: TuningSummary description: Top-line counts for the workbench header. UpdateApiKeyRequest: properties: name: anyOf: - type: string maxLength: 255 minLength: 1 - type: 'null' title: Name scopes: anyOf: - items: type: string type: array - type: 'null' title: Scopes expires_in_days: anyOf: - type: integer maximum: 3650.0 minimum: 1.0 - type: 'null' title: Expires In Days description: Reset TTL from now; 0 = never type: object title: UpdateApiKeyRequest UpdateBody: properties: name: anyOf: - type: string - type: 'null' title: Name description: anyOf: - type: string - type: 'null' title: Description language: anyOf: - type: string - type: 'null' title: Language body: anyOf: - type: string - type: 'null' title: Body enabled: anyOf: - type: boolean - type: 'null' title: Enabled tags: anyOf: - items: type: string type: array - type: 'null' title: Tags mitre: anyOf: - items: type: string type: array - type: 'null' title: Mitre severity: anyOf: - type: string - type: 'null' title: Severity type: object title: UpdateBody UpdateCapabilitiesRequest: properties: allowed_capabilities: anyOf: - items: type: string type: array - type: 'null' title: Allowed Capabilities description: Capability strings (e.g. ['pull_alerts','query_logs']) the agent is permitted to invoke against this instance. None = no downscope. type: object title: UpdateCapabilitiesRequest description: 'Per-instance capability downscoping payload (Workstream 4). ``None`` removes the downscope ("agent may use every capability the connector class declares"). An explicit list — possibly empty — becomes the canonical allow-list. Validation against the connector class''s declared capabilities happens server-side so a tampered request can''t widen the agent''s reach beyond what the connector code actually implements.' UpdateCaseRequest: properties: title: anyOf: - type: string - type: 'null' title: Title description: anyOf: - type: string - type: 'null' title: Description severity: anyOf: - type: string enum: - info - low - medium - high - critical - type: 'null' title: Severity status: anyOf: - type: string enum: - new - triaged - investigating - contained - resolved - closed - type: 'null' title: Status assignee: anyOf: - type: string - type: 'null' title: Assignee mitre_techniques: anyOf: - items: type: string type: array - type: 'null' title: Mitre Techniques compliance_frameworks: anyOf: - items: type: string type: array - type: 'null' title: Compliance Frameworks tags: anyOf: - additionalProperties: type: string type: object - type: 'null' title: Tags sla_due_at: anyOf: - type: string format: date-time - type: 'null' title: Sla Due At type: object title: UpdateCaseRequest UpdateChannel: type: string enum: - stable - beta - nightly - manual title: UpdateChannel UpdateConnectorRequest: properties: name: anyOf: - type: string - type: 'null' title: Name is_enabled: anyOf: - type: boolean - type: 'null' title: Is Enabled auth_config: anyOf: - additionalProperties: true type: object - type: 'null' title: Auth Config connector_config: anyOf: - additionalProperties: true type: object - type: 'null' title: Connector Config tags: anyOf: - items: type: string type: array - type: 'null' title: Tags type: object title: UpdateConnectorRequest UpdateHuntRequest: properties: title: anyOf: - type: string - type: 'null' title: Title hypothesis: anyOf: - type: string - type: 'null' title: Hypothesis mitre_tactic: anyOf: - type: string - type: 'null' title: Mitre Tactic mitre_technique: anyOf: - type: string - type: 'null' title: Mitre Technique status: anyOf: - type: string enum: - draft - active - completed - archived - type: 'null' title: Status priority: anyOf: - type: string enum: - low - medium - high - critical - type: 'null' title: Priority assigned_to: anyOf: - type: string - type: 'null' title: Assigned To query_esql: anyOf: - type: string - type: 'null' title: Query Esql query_spl: anyOf: - type: string - type: 'null' title: Query Spl query_kql: anyOf: - type: string - type: 'null' title: Query Kql tags: anyOf: - items: type: string type: array - type: 'null' title: Tags type: object title: UpdateHuntRequest UpdateObservablesRequest: properties: nodes: items: $ref: '#/components/schemas/ObservableNode' type: array title: Nodes edges: items: $ref: '#/components/schemas/ObservableEdge' type: array title: Edges type: object title: UpdateObservablesRequest UpdateSavedViewRequest: properties: name: anyOf: - type: string maxLength: 120 minLength: 1 - type: 'null' title: Name filters: anyOf: - additionalProperties: true type: object - type: 'null' title: Filters columns: anyOf: - items: {} type: array - additionalProperties: true type: object - type: 'null' title: Columns is_default: anyOf: - type: boolean - type: 'null' title: Is Default additionalProperties: false type: object title: UpdateSavedViewRequest description: 'Partial update — every field is optional. Sending an empty body is a no-op (returns the row unchanged). To *clear* ``columns`` and fall back to the page default column set, the caller passes ``columns: null`` explicitly — the optional / null distinction is preserved in the JSON.' UpdateTaskRequest: properties: title: anyOf: - type: string - type: 'null' title: Title status: anyOf: - type: string enum: - todo - in_progress - done - type: 'null' title: Status assignee: anyOf: - type: string - type: 'null' title: Assignee dueAt: anyOf: - type: string format: date-time - type: 'null' title: Dueat type: object title: UpdateTaskRequest UpdateTenantSettingsRequest: properties: settings: additionalProperties: true type: object title: Settings default: {} type: object title: UpdateTenantSettingsRequest UpdateUserRequest: properties: username: anyOf: - type: string - type: 'null' title: Username role: anyOf: - type: string - type: 'null' title: Role is_active: anyOf: - type: boolean - type: 'null' title: Is Active type: object title: UpdateUserRequest UpsertAlertGraphRequest: properties: alert_id: type: string title: Alert Id title: type: string title: Title severity: type: string title: Severity mitre_techniques: items: type: string type: array title: Mitre Techniques host_id: anyOf: - type: string - type: 'null' title: Host Id user_id: anyOf: - type: string - type: 'null' title: User Id ioc_values: items: type: string type: array title: Ioc Values type: object required: - alert_id - title - severity title: UpsertAlertGraphRequest UpsertCaseGraphRequest: properties: case_id: type: string title: Case Id title: type: string title: Title severity: type: string title: Severity alert_ids: items: type: string type: array title: Alert Ids type: object required: - case_id - title - severity title: UpsertCaseGraphRequest UpsertHostRequest: properties: host_id: type: string title: Host Id hostname: type: string title: Hostname ip_address: type: string title: Ip Address default: '' os: type: string title: Os default: '' criticality: type: string title: Criticality default: medium type: object required: - host_id - hostname title: UpsertHostRequest UpsertUserRequest: properties: user_id: type: string title: User Id username: type: string title: Username email: type: string title: Email default: '' department: type: string title: Department default: '' risk_score: type: number title: Risk Score default: 0.0 type: object required: - user_id - username title: UpsertUserRequest UserMeResponse: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id email: type: string title: Email username: type: string title: Username role: type: string title: Role is_active: type: boolean title: Is Active preferences: additionalProperties: true type: object title: Preferences default: {} type: object required: - id - tenant_id - email - username - role - is_active title: UserMeResponse UserResponse: properties: id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id email: type: string title: Email username: type: string title: Username role: type: string title: Role is_active: type: boolean title: Is Active last_login: anyOf: - type: string format: date-time - type: 'null' title: Last Login created_at: type: string format: date-time title: Created At type: object required: - id - tenant_id - email - username - role - is_active - last_login - created_at title: UserResponse UserRoleAssignment: properties: user_id: type: string format: uuid title: User Id role_id: type: string format: uuid title: Role Id type: object required: - user_id - role_id title: UserRoleAssignment UserRoleOut: properties: user_id: type: string format: uuid title: User Id role_id: type: string format: uuid title: Role Id role_name: type: string title: Role Name type: object required: - user_id - role_id - role_name title: UserRoleOut ValidationError: properties: loc: items: anyOf: - type: string - type: integer type: array title: Location msg: type: string title: Message type: type: string title: Error Type input: title: Input ctx: type: object title: Context type: object required: - loc - msg - type title: ValidationError VulnerabilityCreate: properties: asset_id: type: string format: uuid title: Asset Id cve_id: anyOf: - type: string - type: 'null' title: Cve Id title: type: string title: Title description: anyOf: - type: string - type: 'null' title: Description severity: type: string title: Severity default: medium cvss_score: anyOf: - type: number - type: 'null' title: Cvss Score cvss_vector: anyOf: - type: string - type: 'null' title: Cvss Vector epss_score: anyOf: - type: number - type: 'null' title: Epss Score is_exploited: type: boolean title: Is Exploited default: false source: type: string title: Source external_id: anyOf: - type: string - type: 'null' title: External Id metadata: additionalProperties: true type: object title: Metadata type: object required: - asset_id - title - source title: VulnerabilityCreate VulnerabilityOut: properties: asset_id: type: string format: uuid title: Asset Id cve_id: anyOf: - type: string - type: 'null' title: Cve Id title: type: string title: Title description: anyOf: - type: string - type: 'null' title: Description severity: type: string title: Severity default: medium cvss_score: anyOf: - type: number - type: 'null' title: Cvss Score cvss_vector: anyOf: - type: string - type: 'null' title: Cvss Vector epss_score: anyOf: - type: number - type: 'null' title: Epss Score is_exploited: type: boolean title: Is Exploited default: false source: type: string title: Source external_id: anyOf: - type: string - type: 'null' title: External Id metadata: additionalProperties: true type: object title: Metadata id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id first_found: type: string title: First Found last_found: type: string title: Last Found remediated_at: anyOf: - type: string - type: 'null' title: Remediated At asset_metadata: additionalProperties: true type: object title: Asset Metadata type: object required: - asset_id - title - source - id - tenant_id - first_found - last_found - remediated_at title: VulnerabilityOut WaitlistEntriesResponse: properties: entries: items: $ref: '#/components/schemas/WaitlistEntryWire' type: array title: Entries total: type: integer title: Total type: object required: - entries - total title: WaitlistEntriesResponse WaitlistEntryWire: properties: id: type: string title: Id email: type: string title: Email company: type: string title: Company role: type: string title: Role soc_stack: items: type: string type: array title: Soc Stack motivation: type: string title: Motivation status: type: string title: Status provisioned_tenant_id: anyOf: - type: string - type: 'null' title: Provisioned Tenant Id created_at: type: string title: Created At contacted_at: anyOf: - type: string - type: 'null' title: Contacted At onboarded_at: anyOf: - type: string - type: 'null' title: Onboarded At type: object required: - id - email - company - role - soc_stack - motivation - status - provisioned_tenant_id - created_at - contacted_at - onboarded_at title: WaitlistEntryWire description: Admin-list / admin-patch response shape. WaitlistPatchRequest: properties: status: type: string maxLength: 32 minLength: 1 title: Status type: object required: - status title: WaitlistPatchRequest WaitlistSignupRequest: properties: email: type: string maxLength: 320 minLength: 3 title: Email company: type: string maxLength: 255 minLength: 1 title: Company role: type: string maxLength: 100 minLength: 1 title: Role soc_stack: items: type: string type: array title: Soc Stack motivation: type: string maxLength: 4000 minLength: 1 title: Motivation type: object required: - email - company - role - motivation title: WaitlistSignupRequest description: The exact payload the marketing form posts. WaitlistSignupResponse: properties: ok: type: boolean title: Ok default: true message: type: string title: Message default: We'll be in touch within 5 business days. entry_id: anyOf: - type: string - type: 'null' title: Entry Id type: object title: WaitlistSignupResponse description: 'The reply to a successful (or idempotent-no-op) signup. Same shape whether the email was net-new or already on the list — the prospect should not be able to enumerate existing signups.' WatchlistUpdate: properties: is_watchlisted: type: boolean title: Is Watchlisted watchlist_reason: anyOf: - type: string - type: 'null' title: Watchlist Reason type: object required: - is_watchlisted title: WatchlistUpdate WhitelistCreate: properties: action_type: type: string title: Action Type blast_radius: type: string title: Blast Radius constraints: additionalProperties: true type: object title: Constraints expires_at: anyOf: - type: string format: date-time - type: 'null' title: Expires At type: object required: - action_type - blast_radius title: WhitelistCreate WhitelistOut: properties: action_type: type: string title: Action Type blast_radius: type: string title: Blast Radius constraints: additionalProperties: true type: object title: Constraints expires_at: anyOf: - type: string format: date-time - type: 'null' title: Expires At id: type: string format: uuid title: Id tenant_id: type: string format: uuid title: Tenant Id approved_by: anyOf: - type: string format: uuid - type: 'null' title: Approved By created_at: type: string title: Created At type: object required: - action_type - blast_radius - id - tenant_id - approved_by - created_at title: WhitelistOut app__api__v1__endpoints__business_context__UpdateRuleRequest: properties: yaml: type: string maxLength: 262144 title: Yaml type: object required: - yaml title: UpdateRuleRequest app__api__v1__endpoints__cases__TimelineEvent: properties: id: type: string title: Id type: type: string title: Type timestamp: type: string format: date-time title: Timestamp title: type: string title: Title description: anyOf: - type: string - type: 'null' title: Description actor: anyOf: - type: string - type: 'null' title: Actor type: object required: - id - type - timestamp - title title: TimelineEvent app__api__v1__endpoints__cases__TimelineResponse: properties: events: items: $ref: '#/components/schemas/app__api__v1__endpoints__cases__TimelineEvent' type: array title: Events type: object required: - events title: TimelineResponse app__api__v1__endpoints__detection_rules__HuntResponse: properties: hunt_id: type: string title: Hunt Id rules_evaluated: type: integer title: Rules Evaluated rules_matched: type: integer title: Rules Matched total_events_scanned: type: integer title: Total Events Scanned matched_events: items: additionalProperties: true type: object type: array title: Matched Events match_summary: items: additionalProperties: true type: object type: array title: Match Summary execution_time_ms: type: number title: Execution Time Ms errors: items: type: string type: array title: Errors type: object required: - hunt_id - rules_evaluated - rules_matched - total_events_scanned - matched_events - match_summary - execution_time_ms - errors title: HuntResponse app__api__v1__endpoints__detection_rules__UpdateRuleRequest: properties: name: anyOf: - type: string - type: 'null' title: Name description: anyOf: - type: string - type: 'null' title: Description rule_body: anyOf: - type: string - type: 'null' title: Rule Body status: anyOf: - type: string - type: 'null' title: Status severity: anyOf: - type: string - type: 'null' title: Severity confidence: anyOf: - type: integer - type: 'null' title: Confidence tags: anyOf: - items: type: string type: array - type: 'null' title: Tags type: object title: UpdateRuleRequest app__api__v1__endpoints__hunts__HuntResponse: properties: id: type: string format: uuid title: Id title: type: string title: Title hypothesis: type: string title: Hypothesis mitre_tactic: anyOf: - type: string - type: 'null' title: Mitre Tactic mitre_technique: anyOf: - type: string - type: 'null' title: Mitre Technique status: type: string title: Status priority: type: string title: Priority query_esql: anyOf: - type: string - type: 'null' title: Query Esql query_spl: anyOf: - type: string - type: 'null' title: Query Spl query_kql: anyOf: - type: string - type: 'null' title: Query Kql findings: items: additionalProperties: true type: object type: array title: Findings false_positive_rate: anyOf: - type: number - type: 'null' title: False Positive Rate assigned_to: anyOf: - type: string - type: 'null' title: Assigned To tags: items: type: string type: array title: Tags created_at: type: string format: date-time title: Created At updated_at: type: string format: date-time title: Updated At completed_at: anyOf: - type: string format: date-time - type: 'null' title: Completed At created_by: anyOf: - type: string - type: 'null' title: Created By type: object required: - id - title - hypothesis - mitre_tactic - mitre_technique - status - priority - query_esql - query_spl - query_kql - findings - false_positive_rate - assigned_to - tags - created_at - updated_at - completed_at - created_by title: HuntResponse app__api__v1__endpoints__identity_timeline__TimelineEvent: properties: event_id: type: string format: uuid title: Event Id timestamp: type: string format: date-time title: Timestamp event_type: type: string enum: - alert - login - process - network - file - other title: Event Type source: type: string title: Source description: type: string title: Description severity: anyOf: - type: string - type: 'null' title: Severity mitre_technique: anyOf: - type: string - type: 'null' title: Mitre Technique raw: anyOf: - additionalProperties: true type: object - type: 'null' title: Raw type: object required: - event_id - timestamp - event_type - source - description title: TimelineEvent app__api__v1__endpoints__investigations__TimelineResponse: properties: run_id: type: string format: uuid title: Run Id case_id: type: string title: Case Id status: type: string title: Status total_duration_ms: type: integer title: Total Duration Ms attempt_count: type: integer title: Attempt Count nodes: items: $ref: '#/components/schemas/TimelineNode' type: array title: Nodes type: object required: - run_id - case_id - status - total_duration_ms - attempt_count - nodes title: TimelineResponse description: 'Full timeline for a closed or in-progress run. ``nodes`` are ordered by ``seq`` ascending. ``total_duration_ms`` is the wall-clock span from first to last event. ``attempt_count`` counts unique retry attempts inferred from ``agent_start`` events.' securitySchemes: HTTPBearer: type: http scheme: bearer