{
  "openapi": "3.1.0",
  "info": {
    "title": "Titan Public API",
    "description": "Programmatic access to the Titan platform's public surface. Endpoints\nlive under the `/public/<major>/` path prefix and use OAuth 2.0\nclient-credentials authentication (see the Getting Started guide in\nthe sidebar). Lifecycle state —\nstability, deprecation, sunset — is surfaced on each operation via\nthe lifecycle overlays under `openapi/overlays/lifecycle/`.\n",
    "version": "Beta"
  },
  "tags": [
    {
      "name": "Observations"
    }
  ],
  "paths": {
    "/public/v1/observations": {
      "post": {
        "summary": "List observations",
        "description": "Lists observations with paging, filters, and open/resolved mode. View is server-determined from the caller's domain entitlement.",
        "operationId": "GetObservations",
        "responses": {
          "200": {
            "description": "A successful response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetObservationsResponse"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_ARGUMENT: one or more filter expressions are invalid, or limit/offset/cursor values are out of range.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: access token is absent, malformed, or missing the required organization-domain claim.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "403": {
            "description": "PERMISSION_DENIED: access token does not include the findings.read scope.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "default": {
            "description": "An unexpected error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Status"
                }
              }
            }
          }
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetObservationsRequest"
              }
            }
          },
          "description": "Pagination, filters, and open/resolved mode for listing observations on the public API.\nView (VRM vs self) is determined server-side from the caller's entitlement and is not a request input.",
          "required": true
        },
        "tags": [
          "Observations"
        ],
        "x-stability": "beta",
        "x-version": "1.0.0",
        "x-badges": [
          {
            "name": "Beta",
            "color": "blue",
            "position": "before"
          }
        ]
      }
    },
    "/public/v1/observations/actions/flag": {
      "post": {
        "summary": "Flag observations",
        "description": "Flags observations for follow-up using filter criteria. Returns counts of newly-flagged and already-flagged observations.",
        "operationId": "FlagObservations",
        "responses": {
          "200": {
            "description": "A successful response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FlagObservationsResponse"
                }
              }
            }
          },
          "400": {
            "description": "INVALID_ARGUMENT: one or more filter expressions are invalid.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "401": {
            "description": "UNAUTHENTICATED: access token is absent, malformed, or missing the required organization-domain claim.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "403": {
            "description": "PERMISSION_DENIED: access token does not include the findings.flag scope.",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "default": {
            "description": "An unexpected error response.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Status"
                }
              }
            }
          }
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FlagObservationsRequest"
              }
            }
          },
          "description": "Identifies observations to flag using either an explicit ORN list or filter expressions.",
          "required": true
        },
        "tags": [
          "Observations"
        ],
        "x-stability": "beta",
        "x-version": "1.0.0",
        "x-badges": [
          {
            "name": "Beta",
            "color": "blue",
            "position": "before"
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "AccessType": {
        "type": "string",
        "enum": [
          "ACCESS_TYPE_UNSPECIFIED",
          "ACCESS_TYPE_NO_ACCESS",
          "ACCESS_TYPE_PHYSICAL_ACCESS_ONLY",
          "ACCESS_TYPE_NETWORK_LEVEL_ACCESS",
          "ACCESS_TYPE_SYSTEM_APPLICATION_ACCESS",
          "ACCESS_TYPE_DATA_PROCESSING_STORAGE_ACCESS",
          "ACCESS_TYPE_INFRASTRUCTURE_HOSTING_ACCESS"
        ],
        "default": "ACCESS_TYPE_UNSPECIFIED",
        "description": "Type of access granted to a vendor, as exposed on the public API. Curated\npublic copy of the internal factor_protos.vendor_relationship.v1.AccessType.\nOrdinals are kept IDENTICAL to the internal enum for the same\ncross-boundary-safety reason as VendorLifecycleStatus above.\n\n - ACCESS_TYPE_UNSPECIFIED: Default zero value; access type was not set.\n - ACCESS_TYPE_NO_ACCESS: The vendor has no access to systems, data, or facilities.\n - ACCESS_TYPE_PHYSICAL_ACCESS_ONLY: The vendor has physical access to facilities only (e.g. on-site maintenance);\nno system or data access.\n - ACCESS_TYPE_NETWORK_LEVEL_ACCESS: The vendor has network-level connectivity (e.g. VPN or network segment access)\nwithout direct application or data access.\n - ACCESS_TYPE_SYSTEM_APPLICATION_ACCESS: The vendor has access to specific systems or applications (e.g. a hosted SaaS\naccount) beyond bare network connectivity.\n - ACCESS_TYPE_DATA_PROCESSING_STORAGE_ACCESS: The vendor processes or stores the customer's data directly (e.g. acting as a\ndata processor or subprocessor).\n - ACCESS_TYPE_INFRASTRUCTURE_HOSTING_ACCESS: The vendor hosts or manages underlying infrastructure (e.g. a cloud/hosting\nprovider) that the customer's systems run on."
      },
      "AddVendorToGroupBody": {
        "type": "object",
        "properties": {
          "vendorIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Vendor ids to add. Required, non-empty, capped at 500 per call. A vendor\nalready a member is a no-op, not an error."
          }
        },
        "description": "Vendor ids to add as members of a vendor group. Organization scope is derived\nfrom the access token — this message carries no organization field.",
        "required": [
          "vendorIds"
        ]
      },
      "AddVendorToGroupResponse": {
        "type": "object",
        "properties": {
          "vendorGroup": {
            "$ref": "#/components/schemas/VendorGroup"
          }
        },
        "description": "The vendor group after AddVendorToGroup applies.",
        "required": [
          "vendorGroup"
        ]
      },
      "Any": {
        "type": "object",
        "properties": {
          "@type": {
            "type": "string"
          }
        },
        "additionalProperties": {},
        "required": [
          "typeUrl",
          "value"
        ]
      },
      "ApprovalStatus": {
        "type": "string",
        "enum": [
          "APPROVAL_STATUS_UNSPECIFIED",
          "APPROVAL_STATUS_BACKLOG",
          "APPROVAL_STATUS_TRIAGED_INTERNAL",
          "APPROVAL_STATUS_TRIAGED_EXTERNAL",
          "APPROVAL_STATUS_RESOLVED",
          "APPROVAL_STATUS_EXCLUDED"
        ],
        "default": "APPROVAL_STATUS_UNSPECIFIED",
        "description": "- APPROVAL_STATUS_BACKLOG: An observation that needs to be reviewed. All observations should default to this status\n - APPROVAL_STATUS_TRIAGED_INTERNAL: An observation transitions to this status automatically when a user action takes place using the internal remediation workflow.\n - APPROVAL_STATUS_TRIAGED_EXTERNAL: An observation transitions to this status automatically when a user action takes place using the vendor remediation workflow\n - APPROVAL_STATUS_RESOLVED: An observation that has been determined to be “fixed”.\n - APPROVAL_STATUS_EXCLUDED: The event will usually occur as part of a UX workflow where the user decides to acknowledge and change the state of the observation.",
        "title": "/ Approvaltatus of the remediation from the Vrm/SSC Support/SSC automated system perspective"
      },
      "AssetDns": {
        "type": "object",
        "properties": {
          "recordType": {
            "$ref": "#/components/schemas/AssetDnsType"
          },
          "domain": {
            "type": "string",
            "description": "Fully-qualified domain name that owns the DNS record."
          },
          "record": {
            "type": "string",
            "description": "DNS record name (left-hand side of the zone file entry); absent when not applicable."
          },
          "recordValue": {
            "type": "string",
            "description": "Resolved value of the DNS record (right-hand side of the zone file entry); absent when not applicable."
          }
        },
        "title": "/ AssetDns class",
        "required": [
          "recordType",
          "domain"
        ]
      },
      "AssetDnsType": {
        "type": "string",
        "enum": [
          "ASSET_DNS_TYPE_UNSPECIFIED",
          "ASSET_DNS_TYPE_A",
          "ASSET_DNS_TYPE_AAAA",
          "ASSET_DNS_TYPE_CNAME",
          "ASSET_DNS_TYPE_MX",
          "ASSET_DNS_TYPE_NS",
          "ASSET_DNS_TYPE_PTR",
          "ASSET_DNS_TYPE_SOA",
          "ASSET_DNS_TYPE_SRV",
          "ASSET_DNS_TYPE_TXT",
          "ASSET_DNS_TYPE_CAA",
          "ASSET_DNS_TYPE_DNSKEY",
          "ASSET_DNS_TYPE_DS",
          "ASSET_DNS_TYPE_NAPTR",
          "ASSET_DNS_TYPE_RRSIG",
          "ASSET_DNS_TYPE_TLSA",
          "ASSET_DNS_TYPE_URI"
        ],
        "default": "ASSET_DNS_TYPE_UNSPECIFIED",
        "description": "/ AssetDnsType enumeration. Maps to the different record types in DNS.\n\n - ASSET_DNS_TYPE_A: IPv4 address\n - ASSET_DNS_TYPE_AAAA: IPv6 address\n - ASSET_DNS_TYPE_CNAME: Canonical name\n - ASSET_DNS_TYPE_MX: Mail exchange\n - ASSET_DNS_TYPE_NS: Name server\n - ASSET_DNS_TYPE_PTR: Pointer record\n - ASSET_DNS_TYPE_SOA: Start of authority\n - ASSET_DNS_TYPE_SRV: Service locator\n - ASSET_DNS_TYPE_TXT: Text record\n - ASSET_DNS_TYPE_CAA: Certification Authority Authorization\n - ASSET_DNS_TYPE_DNSKEY: DNSSEC key\n - ASSET_DNS_TYPE_DS: Delegation signer\n - ASSET_DNS_TYPE_NAPTR: Naming authority pointer\n - ASSET_DNS_TYPE_RRSIG: DNSSEC signature\n - ASSET_DNS_TYPE_TLSA: TLS authentication\n - ASSET_DNS_TYPE_URI: URI record"
      },
      "AssetIpPort": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "description": "IPv4 or IPv6 address of the network endpoint being observed."
          },
          "port": {
            "type": "integer",
            "format": "int64",
            "description": "TCP/UDP port number (0–65535) of the endpoint; 0 when not applicable."
          },
          "protocol": {
            "$ref": "#/components/schemas/AssetIpPortProtocol"
          }
        },
        "title": "/ AssetIpPort class - generic for IPv4 and IPv6\n/ Replaces connection_attributes in the metrics API",
        "required": [
          "address",
          "port",
          "protocol"
        ]
      },
      "AssetIpPortProtocol": {
        "type": "string",
        "enum": [
          "ASSET_IP_PORT_PROTOCOL_UNSPECIFIED",
          "ASSET_IP_PORT_PROTOCOL_TCP",
          "ASSET_IP_PORT_PROTOCOL_UDP"
        ],
        "default": "ASSET_IP_PORT_PROTOCOL_UNSPECIFIED",
        "title": "/ AssetIpPortProtocol enumeration"
      },
      "AssetType": {
        "type": "string",
        "enum": [
          "ASSET_TYPE_UNSPECIFIED",
          "ASSET_TYPE_IP_PORT",
          "ASSET_TYPE_URL",
          "ASSET_TYPE_DNS",
          "ASSET_TYPE_CREDENTIALS"
        ],
        "default": "ASSET_TYPE_UNSPECIFIED",
        "title": "/ AssetType enumeration"
      },
      "AssetUrl": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "Fully-qualified URL of the web asset (scheme, host, path, and optional query)."
          }
        },
        "title": "/ AssetUrl class",
        "required": [
          "url"
        ]
      },
      "BulkCreateVendorResult": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "format": "int32",
            "description": "Position of this row in the request's vendors list (0-based), so callers can\npair a result back to its input without relying on domain_name uniqueness."
          },
          "domainName": {
            "type": "string",
            "description": "domain_name as submitted (normalized), echoed for convenience."
          },
          "status": {
            "$ref": "#/components/schemas/BulkVendorMutationStatus"
          },
          "vendorId": {
            "type": "string",
            "description": "Id of the vendor, set when status is SUCCESS or ALREADY_EXISTS."
          },
          "errorMessage": {
            "type": "string",
            "description": "Human-readable detail, set when status is ERROR."
          }
        },
        "description": "Outcome of a single row in a BulkCreateVendors call.",
        "required": [
          "index",
          "domainName",
          "status"
        ]
      },
      "BulkCreateVendorsRequest": {
        "type": "object",
        "properties": {
          "vendors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkCreateVendorsRequestEntry"
            },
            "description": "Rows to create, in the order results are returned. Required and non-empty;\nbounded server-side at 500 entries — a larger batch is rejected with\nINVALID_ARGUMENT before any row is processed."
          }
        },
        "description": "Batch of vendors to create in the caller's directory in one call.\nOrganization scope is derived from the access token, not from this message.",
        "required": [
          "vendors"
        ]
      },
      "BulkCreateVendorsRequestEntry": {
        "type": "object",
        "properties": {
          "domainName": {
            "type": "string",
            "description": "Primary domain name of the vendor (e.g. \"acme.com\"). Required; normalized and\nvalidated server-side."
          },
          "companyName": {
            "type": "string",
            "description": "Display name of the vendor company. Optional; resolved server-side when omitted."
          },
          "dataRegion": {
            "$ref": "#/components/schemas/DataRegion"
          }
        },
        "description": "Writable, curated subset for creating a vendor as one row of a bulk-create batch.\nDeliberately narrower than CreateVendorRequest: the internal bulk-create path only\naccepts a domain and display name per row, so risk/contract/monitoring fields are\nnot available here — set them afterward with UpdateVendor.",
        "required": [
          "domainName"
        ]
      },
      "BulkCreateVendorsResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkCreateVendorResult"
            },
            "description": "Outcome of each row, in request order."
          },
          "summary": {
            "$ref": "#/components/schemas/BulkCreateVendorsResponse.Summary"
          }
        },
        "description": "Per-row results and aggregate summary of a BulkCreateVendors call.",
        "required": [
          "results",
          "summary"
        ]
      },
      "BulkCreateVendorsResponse.Summary": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "format": "int32",
            "description": "Total rows in the request."
          },
          "succeeded": {
            "type": "integer",
            "format": "int32",
            "description": "Rows with status SUCCESS."
          },
          "alreadyExists": {
            "type": "integer",
            "format": "int32",
            "description": "Rows with status ALREADY_EXISTS."
          },
          "failed": {
            "type": "integer",
            "format": "int32",
            "description": "Rows with status ERROR."
          }
        },
        "description": "Aggregate counts of the batch: total, succeeded, already existing, and failed.",
        "required": [
          "total",
          "succeeded",
          "alreadyExists",
          "failed"
        ]
      },
      "BulkDeleteVendorsRequest": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Ids of the vendors to delete, in the order results are returned. Required and\nnon-empty; bounded server-side at 500 entries — a larger batch is rejected with\nINVALID_ARGUMENT before any id is processed."
          }
        },
        "description": "Batch of vendor ids to permanently delete in one call.\nOrganization scope is derived from the access token, not from this message.",
        "required": [
          "ids"
        ]
      },
      "BulkDeleteVendorsResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkVendorIdMutationResult"
            },
            "description": "Outcome of each id, in request order."
          },
          "summary": {
            "$ref": "#/components/schemas/BulkDeleteVendorsResponse.Summary"
          }
        },
        "description": "Per-row results and aggregate summary of a BulkDeleteVendors call.",
        "required": [
          "results",
          "summary"
        ]
      },
      "BulkDeleteVendorsResponse.Summary": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "format": "int32",
            "description": "Total ids in the request."
          },
          "succeeded": {
            "type": "integer",
            "format": "int32",
            "description": "Ids with status SUCCESS."
          },
          "notFound": {
            "type": "integer",
            "format": "int32",
            "description": "Ids with status NOT_FOUND."
          },
          "failed": {
            "type": "integer",
            "format": "int32",
            "description": "Ids with status ERROR."
          }
        },
        "description": "Aggregate counts of the batch: total, succeeded, not found, and failed.",
        "required": [
          "total",
          "succeeded",
          "notFound",
          "failed"
        ]
      },
      "BulkOffboardVendorsRequest": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Ids of the vendors to offboard, in the order results are returned. Required and\nnon-empty; bounded server-side at 500 entries — a larger batch is rejected with\nINVALID_ARGUMENT before any id is processed."
          },
          "reason": {
            "type": "string",
            "description": "Optional caller-supplied audit reason recorded with each offboarding action in\nthis batch."
          }
        },
        "description": "Batch of vendor ids to offboard (archive) in one call, with an optional shared\naudit reason. Organization scope is derived from the access token, not from\nthis message.",
        "required": [
          "ids"
        ]
      },
      "BulkOffboardVendorsResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkVendorIdMutationResult"
            },
            "description": "Outcome of each id, in request order."
          },
          "summary": {
            "$ref": "#/components/schemas/BulkOffboardVendorsResponse.Summary"
          }
        },
        "description": "Per-row results and aggregate summary of a BulkOffboardVendors call.",
        "required": [
          "results",
          "summary"
        ]
      },
      "BulkOffboardVendorsResponse.Summary": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "format": "int32",
            "description": "Total ids in the request."
          },
          "succeeded": {
            "type": "integer",
            "format": "int32",
            "description": "Ids with status SUCCESS (including a no-op on an already-offboarded vendor)."
          },
          "notFound": {
            "type": "integer",
            "format": "int32",
            "description": "Ids with status NOT_FOUND."
          },
          "failed": {
            "type": "integer",
            "format": "int32",
            "description": "Ids with status ERROR."
          }
        },
        "description": "Aggregate counts of the batch: total, succeeded (including already-offboarded\nno-ops), not found, and failed.",
        "required": [
          "total",
          "succeeded",
          "notFound",
          "failed"
        ]
      },
      "BulkUpsertVendorsFromCsvRequest": {
        "type": "object",
        "properties": {
          "csv": {
            "type": "string",
            "description": "Raw CSV text to import; column layout matches the vendor directory's curated\nwritable fields (domain_name, company_name, and the other columns supported for\nthe caller's organization). Required and non-empty."
          },
          "dryRun": {
            "type": "boolean",
            "description": "When true, validates every row and returns the per-row outcomes it would produce\nwithout persisting any changes. Optional; defaults to false."
          }
        },
        "description": "Body for BulkUpsertVendorsFromCsv: raw CSV text of vendors to upsert in the\ncaller's directory. Organization scope is derived from the access token, not\nfrom this message.",
        "required": [
          "csv"
        ]
      },
      "BulkUpsertVendorsFromCsvResponse": {
        "type": "object",
        "properties": {
          "rowResults": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkVendorCsvRowResult"
            },
            "description": "Per-row outcome, in the order rows appeared in the submitted CSV."
          },
          "summary": {
            "$ref": "#/components/schemas/BulkUpsertVendorsFromCsvResponse.Summary"
          }
        },
        "description": "Aggregate counts and per-row results after processing a vendor bulk CSV import.",
        "required": [
          "rowResults",
          "summary"
        ]
      },
      "BulkUpsertVendorsFromCsvResponse.Summary": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "format": "int32",
            "description": "Total rows in the submitted CSV, excluding the header row."
          },
          "accepted": {
            "type": "integer",
            "format": "int32",
            "description": "Rows with outcome ACCEPTED."
          },
          "rejected": {
            "type": "integer",
            "format": "int32",
            "description": "Rows with outcome REJECTED."
          },
          "skipped": {
            "type": "integer",
            "format": "int32",
            "description": "Rows with outcome SKIPPED."
          }
        },
        "description": "Aggregate counts of the batch: total, accepted, rejected, and skipped.",
        "required": [
          "total",
          "accepted",
          "rejected",
          "skipped"
        ]
      },
      "BulkVendorCsvRowOutcome": {
        "type": "string",
        "enum": [
          "BULK_VENDOR_CSV_ROW_OUTCOME_UNSPECIFIED",
          "BULK_VENDOR_CSV_ROW_OUTCOME_ACCEPTED",
          "BULK_VENDOR_CSV_ROW_OUTCOME_REJECTED",
          "BULK_VENDOR_CSV_ROW_OUTCOME_SKIPPED"
        ],
        "default": "BULK_VENDOR_CSV_ROW_OUTCOME_UNSPECIFIED",
        "description": "Outcome of a single row in a BulkUpsertVendorsFromCsv call.\n\n - BULK_VENDOR_CSV_ROW_OUTCOME_UNSPECIFIED: Default zero value; outcome was not set.\n - BULK_VENDOR_CSV_ROW_OUTCOME_ACCEPTED: The row was validated and (unless dry_run) applied successfully.\n - BULK_VENDOR_CSV_ROW_OUTCOME_REJECTED: The row failed validation and was not applied; code/message carry detail.\n - BULK_VENDOR_CSV_ROW_OUTCOME_SKIPPED: The row was structurally valid but not applied for a non-error reason (e.g. a\nduplicate row within the same file); code/message carry detail."
      },
      "BulkVendorCsvRowResult": {
        "type": "object",
        "properties": {
          "rowIndex": {
            "type": "integer",
            "format": "int64",
            "description": "1-based row number in the submitted CSV, excluding the header row."
          },
          "outcome": {
            "$ref": "#/components/schemas/BulkVendorCsvRowOutcome"
          },
          "code": {
            "type": "string",
            "description": "Machine-readable reason code, set when outcome is REJECTED or SKIPPED\n(e.g. \"INVALID_DOMAIN\", \"DUPLICATE_ROW\")."
          },
          "message": {
            "type": "string",
            "description": "Human-readable detail, set when outcome is REJECTED or SKIPPED."
          }
        },
        "description": "Per-row result from a bulk CSV import.",
        "required": [
          "rowIndex",
          "outcome"
        ]
      },
      "BulkVendorIdMutationResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Id as submitted, echoed for convenience."
          },
          "status": {
            "$ref": "#/components/schemas/BulkVendorMutationStatus"
          },
          "errorMessage": {
            "type": "string",
            "description": "Human-readable detail, set when status is ERROR."
          }
        },
        "description": "Outcome of a single id in a BulkDeleteVendors or BulkOffboardVendors call.",
        "required": [
          "id",
          "status"
        ]
      },
      "BulkVendorMutationStatus": {
        "type": "string",
        "enum": [
          "BULK_VENDOR_MUTATION_STATUS_UNSPECIFIED",
          "BULK_VENDOR_MUTATION_STATUS_SUCCESS",
          "BULK_VENDOR_MUTATION_STATUS_ALREADY_EXISTS",
          "BULK_VENDOR_MUTATION_STATUS_NOT_FOUND",
          "BULK_VENDOR_MUTATION_STATUS_ERROR"
        ],
        "default": "BULK_VENDOR_MUTATION_STATUS_UNSPECIFIED",
        "description": "Outcome of a single row in a bulk vendor mutation (create, delete, or offboard).\nShared across BulkCreateVendors, BulkDeleteVendors, and BulkOffboardVendors so\ncallers handle partial failure the same way regardless of which bulk call they made.\n\n - BULK_VENDOR_MUTATION_STATUS_UNSPECIFIED: Default zero value; status was not set.\n - BULK_VENDOR_MUTATION_STATUS_SUCCESS: The row was applied successfully.\n - BULK_VENDOR_MUTATION_STATUS_ALREADY_EXISTS: BulkCreateVendors only: a vendor with the same domain already exists in the\ncaller's directory; no new row was created.\n - BULK_VENDOR_MUTATION_STATUS_NOT_FOUND: BulkDeleteVendors / BulkOffboardVendors only: no vendor with the given id\nexists within the caller's organization.\n - BULK_VENDOR_MUTATION_STATUS_ERROR: The row failed for a reason not covered above (e.g. malformed domain_name);\nerror_message on the row carries detail."
      },
      "BusinessImpact": {
        "type": "string",
        "enum": [
          "BUSINESS_IMPACT_UNSPECIFIED",
          "BUSINESS_IMPACT_NONE",
          "BUSINESS_IMPACT_LOW",
          "BUSINESS_IMPACT_MEDIUM",
          "BUSINESS_IMPACT_HIGH",
          "BUSINESS_IMPACT_CRITICAL"
        ],
        "default": "BUSINESS_IMPACT_UNSPECIFIED",
        "description": "Business impact if a vendor is compromised, as exposed on the public API.\nCurated public copy of the internal\nfactor_protos.vendor_relationship.v1.BusinessImpact. Ordinals are kept\nIDENTICAL to the internal enum for the same cross-boundary-safety reason as\nVendorLifecycleStatus above.\n\n - BUSINESS_IMPACT_UNSPECIFIED: Default zero value; business impact was not set.\n - BUSINESS_IMPACT_NONE: No material impact to the business if this vendor is compromised.\n - BUSINESS_IMPACT_LOW: Limited, easily contained disruption.\n - BUSINESS_IMPACT_MEDIUM: Noticeable disruption to some business functions.\n - BUSINESS_IMPACT_HIGH: Significant disruption to core business functions.\n - BUSINESS_IMPACT_CRITICAL: Severe, potentially existential disruption to the business."
      },
      "CapecData": {
        "type": "object",
        "properties": {
          "capecId": {
            "type": "string",
            "description": "CAPEC identifier for the attack pattern (e.g. \"CAPEC-66\")."
          },
          "summary": {
            "type": "string",
            "description": "Short, one-sentence summary of the attack pattern."
          },
          "description": {
            "type": "string",
            "description": "Full narrative describing how the attack is carried out and what it targets."
          }
        },
        "title": "/ CapecData class",
        "required": [
          "capecId",
          "summary",
          "description"
        ]
      },
      "CompanyContact": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string",
            "description": "Domain of the company the contacts belong to."
          },
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/v1.Contact"
            },
            "description": "Contacts at this company to receive the remediation-request email."
          }
        },
        "description": "A company domain with the contacts at that company to receive remediation-request emails.",
        "required": [
          "domain",
          "contacts"
        ]
      },
      "CreateQuestionnaireRequest": {
        "type": "object",
        "properties": {
          "templateId": {
            "type": "string",
            "description": "Id of the template to create the questionnaire from. Required."
          },
          "vendorId": {
            "type": "string",
            "description": "Id of the vendor (in the caller's directory) to create the questionnaire for. Required."
          }
        },
        "description": "Request to create a questionnaire from a template for a vendor.",
        "required": [
          "templateId",
          "vendorId"
        ]
      },
      "CreateQuestionnaireResponse": {
        "type": "object",
        "properties": {
          "questionnaire": {
            "$ref": "#/components/schemas/Questionnaire"
          }
        },
        "description": "Response containing the newly created questionnaire.",
        "required": [
          "questionnaire"
        ]
      },
      "CreateVendorGroupRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Human-readable display name for the new group. Required and must be non-blank after\nsurrounding whitespace is trimmed; at most 255 characters. Must not duplicate the name\nof an active group in the caller's organization — a duplicate is rejected with\nALREADY_EXISTS rather than creating a second group."
          },
          "description": {
            "type": "string",
            "description": "Free-text description of the group; at most 1024 characters. Omit when the caller has\nno copy to store — an omitted description reads back absent on the created group."
          }
        },
        "description": "The curated writable subset accepted when creating a vendor group.\n\nDeliberately narrow: everything else on the internal\nfactor_protos.vendor_relationship.v1.CreateVendorGroupRequest is server-owned and\nnever accepted from a public caller. Intentionally excluded:\n  customer_organization_id – derived from the caller's access token, so accepting it\n                             would let a caller assert another org's directory.\n  organizational_unit_id   – an internal scoping mechanism, not a customer-facing\n                             concept; the service mirrors it from the organization.\n  created_by / updated_by  – internal audit subject identifiers, set server-side from\n                             the OAuth2 client.\n  member_count             – maintained by the service; a new group always starts empty.\n  created_at / updated_at  – server-assigned timestamps.",
        "required": [
          "name"
        ]
      },
      "CreateVendorGroupResponse": {
        "type": "object",
        "properties": {
          "vendorGroup": {
            "$ref": "#/components/schemas/VendorGroup"
          }
        },
        "description": "The vendor group created by CreateVendorGroup.",
        "required": [
          "vendorGroup"
        ]
      },
      "CreateVendorRequest": {
        "type": "object",
        "properties": {
          "domainName": {
            "type": "string",
            "description": "Primary domain name of the vendor (e.g. \"acme.com\"). Required; normalized and\nvalidated server-side, and deduplicated against the caller's existing directory\n(organization + domain_name) — a domain already present is rejected with\nALREADY_EXISTS."
          },
          "companyName": {
            "type": "string",
            "description": "Display name of the vendor company. Optional; resolved server-side when omitted."
          },
          "vendorId": {
            "type": "string",
            "description": "Customer-defined free-text identifier for the vendor (the caller's own external\nreference, not the internal entity id). Optional."
          },
          "isMonitored": {
            "type": "boolean",
            "description": "Whether the vendor should be actively monitored. Optional; when omitted the\nvendor is created not monitored (consumes no monitoring slot)."
          },
          "riskLevel": {
            "$ref": "#/components/schemas/RiskLevel"
          },
          "businessImpact": {
            "$ref": "#/components/schemas/BusinessImpact"
          },
          "dataTypesShared": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DataTypeShared"
            },
            "description": "Categories of data shared with the vendor. Optional; repeated."
          },
          "accessTypes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccessType"
            },
            "description": "Types of access granted to the vendor. Optional; repeated."
          },
          "contractValue": {
            "type": "string",
            "format": "int64",
            "description": "Monetary value of the contract, in the minor units of the customer account's\ncurrency (e.g. cents for a USD account) — the same representation as\nVendor.contract_value. Optional."
          },
          "contractEndDate": {
            "type": "string",
            "format": "date-time",
            "description": "Date the vendor contract expires. Optional; absent when not set. Same\nrepresentation as Vendor.contract_end_date."
          },
          "dataRegion": {
            "$ref": "#/components/schemas/DataRegion"
          }
        },
        "description": "Writable, curated subset for creating a vendor in the caller's directory.\n\nDeliberately narrow: it carries ONLY the fields a public caller may set at\ncreate time. It has NO customer_organization_id — the organization is derived\nserver-side from the caller's access token, never this message — and no internal\nids, audit actors, or contact PII. Field numbers are scoped to this message and\nare independent of the internal create contract; field TYPES intentionally mirror\nthe curated Vendor response (same enums, same contract_value minor-units and\ncontract_end_date Timestamp representation) so input and output speak the same\nshapes.",
        "required": [
          "domainName",
          "dataTypesShared",
          "accessTypes",
          "contractEndDate"
        ]
      },
      "CreateVendorResponse": {
        "type": "object",
        "properties": {
          "vendor": {
            "$ref": "#/components/schemas/vendor.v1.Vendor"
          }
        },
        "description": "Response containing the newly created vendor.",
        "required": [
          "vendor"
        ]
      },
      "CvssScore": {
        "type": "object",
        "properties": {
          "version": {
            "$ref": "#/components/schemas/CvssScoreVersion"
          },
          "baseScore": {
            "type": "number",
            "format": "float",
            "description": "Numeric base score on a 0.0–10.0 scale as defined by the CVSS standard."
          },
          "baseSeverity": {
            "$ref": "#/components/schemas/CvssScoreSeverity"
          },
          "cvssVector": {
            "type": "string",
            "description": "Compact CVSS vector string encoding all metric values (e.g. \"CVSS:3.1/AV:N/AC:L/...\")."
          },
          "exploitabilityScore": {
            "type": "number",
            "format": "float",
            "description": "Sub-score measuring ease of exploitation; absent when the scoring source did not compute it."
          },
          "impactScore": {
            "type": "number",
            "format": "float",
            "description": "Sub-score measuring the consequence to confidentiality, integrity, and availability; absent when not computed."
          },
          "scoreSource": {
            "type": "string",
            "description": "Organization or feed that published this score (e.g. \"NVD\", \"vendor\")."
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time",
            "description": "When this CVSS score was first recorded for the CVE."
          },
          "references": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CvssScoreReference"
            },
            "description": "External references (advisories, patches, NVD entries) that support this score."
          }
        },
        "title": "/ CvssScore class",
        "required": [
          "version",
          "baseScore",
          "baseSeverity",
          "cvssVector",
          "scoreSource",
          "firstSeen",
          "references"
        ]
      },
      "CvssScoreReference": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "URL of the external advisory, patch note, or NVD/vendor page that supports this score."
          },
          "description": {
            "type": "string",
            "description": "Human-readable summary of what the reference describes; absent when not provided by the source."
          }
        },
        "title": "/ CvssScoreReference class",
        "required": [
          "url"
        ]
      },
      "CvssScoreSeverity": {
        "type": "string",
        "enum": [
          "CVSS_SCORE_SEVERITY_UNSPECIFIED",
          "CVSS_SCORE_SEVERITY_LOW",
          "CVSS_SCORE_SEVERITY_MEDIUM",
          "CVSS_SCORE_SEVERITY_HIGH",
          "CVSS_SCORE_SEVERITY_CRITICAL"
        ],
        "default": "CVSS_SCORE_SEVERITY_UNSPECIFIED",
        "title": "/ CvssScoreSeverity enumeration"
      },
      "CvssScoreVersion": {
        "type": "string",
        "enum": [
          "CVSS_SCORE_VERSION_UNSPECIFIED",
          "CVSS_SCORE_VERSION_1_0",
          "CVSS_SCORE_VERSION_2_0",
          "CVSS_SCORE_VERSION_3_0",
          "CVSS_SCORE_VERSION_3_1",
          "CVSS_SCORE_VERSION_4"
        ],
        "default": "CVSS_SCORE_VERSION_UNSPECIFIED",
        "title": "/ CvssScoreVersion enumeration"
      },
      "CweData": {
        "type": "object",
        "properties": {
          "cweId": {
            "type": "string",
            "description": "CWE identifier for the weakness class (e.g. \"CWE-79\")."
          },
          "summary": {
            "type": "string",
            "description": "Short, one-sentence summary of the weakness."
          },
          "description": {
            "type": "string",
            "description": "Full narrative describing the root-cause weakness and its consequences."
          },
          "relatedCapec": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CapecData"
            },
            "description": "CAPEC attack patterns that exploit this weakness, when available."
          }
        },
        "title": "/ CweData class",
        "required": [
          "cweId",
          "summary",
          "description",
          "relatedCapec"
        ]
      },
      "DataRegion": {
        "type": "string",
        "enum": [
          "DATA_REGION_UNSPECIFIED",
          "DATA_REGION_US",
          "DATA_REGION_EU",
          "DATA_REGION_UK",
          "DATA_REGION_CA",
          "DATA_REGION_AU",
          "DATA_REGION_APAC"
        ],
        "default": "DATA_REGION_UNSPECIFIED",
        "description": "Data region where a vendor operates, as exposed on the public API. Curated public\ncopy of the internal DataRegion. Ordinals are kept IDENTICAL to the internal enum\nfor the same reason as VendorLifecycleStatus above (enum values can cross the\npublic/internal boundary by number, so the numbers must stay aligned). It happens\nto be value-for-value identical today; keep it that way as the internal enum evolves.\n\n - DATA_REGION_UNSPECIFIED: Default zero value; data region was not set.\n - DATA_REGION_US: United States.\n - DATA_REGION_EU: European Union.\n - DATA_REGION_UK: United Kingdom.\n - DATA_REGION_CA: Canada.\n - DATA_REGION_AU: Australia.\n - DATA_REGION_APAC: Asia-Pacific."
      },
      "DataTypeShared": {
        "type": "string",
        "enum": [
          "DATA_TYPE_SHARED_UNSPECIFIED",
          "DATA_TYPE_SHARED_PII",
          "DATA_TYPE_SHARED_PHI",
          "DATA_TYPE_SHARED_SENSITIVE",
          "DATA_TYPE_SHARED_FINANCIAL",
          "DATA_TYPE_SHARED_INTELLECTUAL_PROPERTY"
        ],
        "default": "DATA_TYPE_SHARED_UNSPECIFIED",
        "description": "Category of data shared with a vendor, as exposed on the public API. Curated\npublic copy of the internal factor_protos.vendor_relationship.v1.DataTypeShared.\nOrdinals are kept IDENTICAL to the internal enum for the same\ncross-boundary-safety reason as VendorLifecycleStatus above.\n\n - DATA_TYPE_SHARED_UNSPECIFIED: Default zero value; data type was not set.\n - DATA_TYPE_SHARED_PII: Personally identifiable information (e.g. names, government IDs, contact details).\n - DATA_TYPE_SHARED_PHI: Protected health information (e.g. medical records, health insurance data).\n - DATA_TYPE_SHARED_SENSITIVE: Other sensitive data not covered by PII/PHI/financial (e.g. credentials, trade secrets).\n - DATA_TYPE_SHARED_FINANCIAL: Financial data (e.g. payment card numbers, bank account details, transaction records).\n - DATA_TYPE_SHARED_INTELLECTUAL_PROPERTY: Intellectual property (e.g. proprietary source code, patents, unpublished research)."
      },
      "DateRange": {
        "type": "object",
        "properties": {
          "startTime": {
            "type": "string",
            "format": "date-time",
            "title": "Inclusive"
          },
          "endTime": {
            "type": "string",
            "format": "date-time",
            "title": "Inclusive"
          },
          "live": {
            "type": "boolean"
          }
        },
        "description": "Wall-clock window for time-based filters; optional live flag for rolling “now” semantics."
      },
      "DateRangeBounds": {
        "type": "object",
        "properties": {
          "earliestDate": {
            "type": "string",
            "format": "date-time",
            "title": "Earliest allowable date (inclusive)"
          },
          "latestDate": {
            "type": "string",
            "format": "date-time",
            "title": "Latest allowable date (inclusive)"
          }
        },
        "description": "Earliest and latest timestamps permitted for date or datetime filters."
      },
      "DiscreteFilterValues": {
        "type": "object",
        "properties": {
          "values": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterOptionValue"
            }
          }
        },
        "description": "Enumerated pick-list entries returned to populate filter dropdowns or chips.",
        "required": [
          "values"
        ]
      },
      "EpssHistory": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date-time",
            "description": "Date on which the EPSS score was recorded."
          },
          "score": {
            "type": "number",
            "format": "float",
            "description": "EPSS probability score (0.0–1.0) on the given date; absent if not available for that date."
          }
        },
        "title": "/ EpssHistory class",
        "required": [
          "date"
        ]
      },
      "Evidence": {
        "type": "object",
        "properties": {
          "advertising": {
            "$ref": "#/components/schemas/EvidenceAdvertising"
          },
          "appsec": {
            "$ref": "#/components/schemas/EvidenceAppsec"
          },
          "clearWebCert": {
            "$ref": "#/components/schemas/EvidenceClearWebCert"
          },
          "clearWebEvidence": {
            "$ref": "#/components/schemas/EvidenceClearWebEvidence"
          },
          "compromisedStealer": {
            "$ref": "#/components/schemas/EvidenceCompromisedStealer"
          },
          "cookie": {
            "$ref": "#/components/schemas/EvidenceCookie"
          },
          "domainSquatting": {
            "$ref": "#/components/schemas/EvidenceDomainSquatting"
          },
          "exploitedProduct": {
            "$ref": "#/components/schemas/EvidenceExploitedProduct"
          },
          "hackerChatter": {
            "$ref": "#/components/schemas/EvidenceHackerChatter"
          },
          "leakedCredentialsV2": {
            "$ref": "#/components/schemas/EvidenceLeakedCredentialsV2"
          },
          "malware": {
            "$ref": "#/components/schemas/EvidenceMalware"
          },
          "openSslVuln": {
            "$ref": "#/components/schemas/EvidenceOpenSSLVuln"
          },
          "patchingAnalysis": {
            "$ref": "#/components/schemas/EvidencePatchingAnalysis"
          },
          "potentiallyVulnerable": {
            "$ref": "#/components/schemas/EvidencePotentiallyVulnerable"
          },
          "ransomwareAssociation": {
            "$ref": "#/components/schemas/EvidenceRansomwareAssociation"
          },
          "ransomwareVictim": {
            "$ref": "#/components/schemas/EvidenceRansomwareVictim"
          },
          "spf": {
            "$ref": "#/components/schemas/EvidenceSPF"
          },
          "ssh": {
            "$ref": "#/components/schemas/EvidenceSSH"
          },
          "service": {
            "$ref": "#/components/schemas/EvidenceService"
          },
          "skynet": {
            "$ref": "#/components/schemas/EvidenceSkynet"
          },
          "synthHighRiskAppsecAccess": {
            "$ref": "#/components/schemas/EvidenceSynthHighRiskAppsecAccess"
          },
          "synthPossibleInitialAccess": {
            "$ref": "#/components/schemas/EvidenceSynthPossibleInitialAccess"
          },
          "tls": {
            "$ref": "#/components/schemas/EvidenceTLS"
          },
          "torExitNode": {
            "$ref": "#/components/schemas/EvidenceTorExitNode"
          },
          "vulnerability": {
            "$ref": "#/components/schemas/EvidenceVulnerability"
          },
          "x509": {
            "$ref": "#/components/schemas/EvidenceX509"
          },
          "breach": {
            "$ref": "#/components/schemas/EvidenceBreach"
          },
          "serviceScan": {
            "$ref": "#/components/schemas/EvidenceServiceScan"
          },
          "productsDetected": {
            "$ref": "#/components/schemas/EvidenceProductsDetected"
          },
          "detectedVendor": {
            "$ref": "#/components/schemas/EvidenceDetectedVendor"
          }
        },
        "description": "Discriminated union of all structured evidence blobs that can justify a raw observation."
      },
      "EvidenceAdvertising": {
        "type": "object",
        "properties": {
          "productManufacturer": {
            "type": "string",
            "description": "Vendor or company that produced the detected product."
          },
          "productName": {
            "type": "string",
            "description": "Name of the identified software product or library."
          },
          "productVersion": {
            "type": "string",
            "description": "Detected version string of the product."
          },
          "productStateStatus": {
            "type": "string",
            "description": "Observed operational state of the product (e.g. \"active\", \"deprecated\")."
          },
          "userAgent": {
            "type": "string",
            "description": "HTTP User-Agent header value captured during the crawl."
          },
          "evidence": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Raw proof strings from the crawl that confirm the product presence."
          }
        },
        "description": "Ad-tech or client fingerprint leak: product metadata, user agent, and free-form proof strings from the crawl.",
        "required": [
          "productManufacturer",
          "productName",
          "productVersion",
          "productStateStatus",
          "userAgent",
          "evidence"
        ]
      },
      "EvidenceAppsec": {
        "type": "object",
        "properties": {
          "analysis": {
            "type": "string"
          },
          "scheme": {
            "type": "string"
          },
          "observations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvidenceAppsecObservation"
            }
          }
        },
        "description": "AppSec narrative for an asset: high-level analysis, scheme context, and supporting URL-level observations.",
        "required": [
          "analysis",
          "scheme",
          "observations"
        ]
      },
      "EvidenceAppsecObservation": {
        "type": "object",
        "properties": {
          "initialUrl": {
            "type": "string",
            "description": "URL at which the crawl request originated (before any redirects)."
          },
          "finalUrl": {
            "type": "string",
            "description": "Final URL reached after following the redirect chain."
          },
          "evidence": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Raw proof strings captured during the crawl that confirm the finding."
          },
          "lastSeenAt": {
            "type": "string",
            "format": "date-time",
            "description": "When this crawl observation was last confirmed active."
          }
        },
        "description": "Single app-security crawl hop: redirect chain, textual proof points, and recency for an exposed issue.",
        "required": [
          "initialUrl",
          "finalUrl",
          "evidence",
          "lastSeenAt"
        ]
      },
      "EvidenceBreach": {
        "type": "object",
        "properties": {
          "clusterId": {
            "type": "string",
            "title": "UUID representing the cluster of entries"
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "breachItems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvidenceBreachItem"
            },
            "title": "all the BreachItems"
          },
          "createdAt": {
            "type": "string",
            "title": "ISO-8601 string without timezone"
          },
          "publishedDate": {
            "type": "string",
            "title": "ISO-8601 string without timezone"
          },
          "breachDate": {
            "type": "string",
            "title": "ISO-8601 string without timezone"
          },
          "recordsLost": {
            "type": "integer",
            "format": "int32",
            "title": "maximum of all the records lost from breach_items"
          },
          "confirmed": {
            "type": "boolean"
          },
          "originatingParty": {
            "type": "string"
          }
        },
        "description": "Clustered public-breach narrative with summary metadata and all supporting breach item rows.",
        "required": [
          "clusterId",
          "title",
          "summary",
          "breachItems",
          "createdAt",
          "publishedDate",
          "confirmed"
        ]
      },
      "EvidenceBreachItem": {
        "type": "object",
        "properties": {
          "clusterId": {
            "type": "string",
            "title": "FK to BreachObject"
          },
          "itemId": {
            "type": "string",
            "title": "Primary key"
          },
          "title": {
            "type": "string"
          },
          "link": {
            "type": "string"
          },
          "sourceType": {
            "type": "string"
          },
          "publishedDate": {
            "type": "string",
            "title": "ISO-8601 string"
          },
          "originatingParty": {
            "type": "string"
          },
          "affectedParties": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "threatActors": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "breachDate": {
            "type": "string",
            "title": "ISO-8601 string"
          },
          "recordsLost": {
            "type": "integer",
            "format": "int32"
          },
          "sourceReliability": {
            "type": "number",
            "format": "float"
          },
          "createdAt": {
            "type": "string",
            "title": "ISO-8601 string"
          },
          "updatedAt": {
            "type": "string",
            "title": "ISO-8601 string"
          },
          "infoLeaked": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "One article or OSINT record inside a broader breach cluster (actors, victims, dates, reliability).",
        "required": [
          "clusterId",
          "itemId",
          "title",
          "link",
          "sourceType",
          "publishedDate",
          "affectedParties",
          "threatActors",
          "sourceReliability",
          "createdAt",
          "updatedAt",
          "infoLeaked"
        ]
      },
      "EvidenceClearWebCert": {
        "type": "object",
        "properties": {
          "organization": {
            "type": "string",
            "description": "Organization name from the certificate's Subject field."
          },
          "signatureAlgorithm": {
            "type": "string",
            "description": "Signature algorithm used to sign the certificate (e.g. \"sha256WithRSAEncryption\")."
          },
          "notbefore": {
            "type": "string",
            "description": "Certificate validity start date (ISO-8601 string)."
          },
          "notafter": {
            "type": "string",
            "description": "Certificate expiry date (ISO-8601 string)."
          },
          "cn": {
            "type": "string",
            "description": "Common Name from the certificate's Subject field (typically the primary hostname)."
          },
          "issuerName": {
            "type": "string",
            "description": "Distinguished name of the certificate authority that issued this certificate."
          },
          "dataSource": {
            "type": "string",
            "description": "Feed or scanner that discovered this certificate."
          }
        },
        "description": "X.509 attributes captured from clear-web discovery: subject, validity window, issuer, and provenance source.",
        "required": [
          "organization",
          "signatureAlgorithm",
          "notbefore",
          "notafter",
          "cn",
          "issuerName",
          "dataSource"
        ]
      },
      "EvidenceClearWebEvidence": {
        "type": "object",
        "properties": {
          "observations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvidenceClearWebEvidenceObservation"
            }
          },
          "dataSource": {
            "type": "string"
          }
        },
        "description": "Batched clear-web findings plus the data source that produced them.",
        "required": [
          "observations",
          "dataSource"
        ]
      },
      "EvidenceClearWebEvidenceObservation": {
        "type": "object",
        "properties": {
          "content": {
            "type": "string"
          },
          "match": {
            "type": "string"
          },
          "specific": {
            "type": "string"
          }
        },
        "description": "Clear-web crawl hit: raw content excerpt, matched pattern, and specificity hint for DLP-style issues.",
        "required": [
          "content",
          "match",
          "specific"
        ]
      },
      "EvidenceCompromisedStealer": {
        "type": "object",
        "properties": {
          "location": {
            "type": "string",
            "description": "Country or city where the compromised host was located at the time of infection."
          },
          "region": {
            "type": "string",
            "description": "Sub-national region or state of the compromised host."
          },
          "userName": {
            "type": "string",
            "description": "Username or account name extracted from the stealer log."
          },
          "operatingSystem": {
            "type": "string",
            "description": "Operating system of the compromised host (e.g. \"Windows 10\")."
          },
          "eventDate": {
            "type": "string",
            "description": "Date the stealer malware logged the credential theft (ISO-8601 string)."
          },
          "informationLeaked": {
            "type": "string",
            "description": "Summary of credential types or data categories captured (e.g. \"passwords, cookies\")."
          }
        },
        "description": "Stealer-log style compromise row: geography, host, user, OS, leaked data summary, and event timing.",
        "required": [
          "location",
          "region",
          "userName",
          "operatingSystem",
          "eventDate",
          "informationLeaked"
        ]
      },
      "EvidenceCookie": {
        "type": "object",
        "properties": {
          "observations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvidenceCookieObservation"
            }
          }
        },
        "description": "Aggregated risky HTTP cookies for an asset by rolling up repeated EvidenceCookieObservation samples.",
        "required": [
          "observations"
        ]
      },
      "EvidenceCookieObservation": {
        "type": "object",
        "properties": {
          "cookieName": {
            "type": "string"
          },
          "rawCookie": {
            "type": "string"
          },
          "lastSeenAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "One sighting of a sensitive HTTP cookie: optional name, raw value, and last time it was observed.",
        "required": [
          "lastSeenAt"
        ]
      },
      "EvidenceDetectedVendor": {
        "type": "object",
        "properties": {
          "detectedVendors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvidenceDetectedVendorObservation"
            },
            "description": "One entry per (vendor_asset, vendor_connection_type) tuple derived from this observation\n(with `vendor_organization_domain` rolling up that asset to its owning organization where\navailable). Empty lists are NOT expected."
          }
        },
        "description": "Wrapper carrying all vendor-connection observations derived from a single RawObservation.\nA RawObservation is 1:N over the (vendor_asset, vendor_connection_type) tuples exposed here;\nthe consumer fan-outs to one storage row per entry in {@code detected_vendors}.",
        "required": [
          "detectedVendors"
        ]
      },
      "EvidenceDetectedVendorObservation": {
        "type": "object",
        "properties": {
          "vendorIpAndPort": {
            "$ref": "#/components/schemas/AssetIpPort"
          },
          "vendorUrl": {
            "$ref": "#/components/schemas/AssetUrl"
          },
          "vendorDns": {
            "$ref": "#/components/schemas/AssetDns"
          },
          "vendorOrganizationDomain": {
            "type": "string",
            "description": "Apex domain of the vendor's owning organization / scorecard (e.g. `abc.xyz` for the\n`google.com` vendor asset). The producer fills this when it can attribute the vendor asset\nto a parent organization; left empty otherwise."
          },
          "vendorConnectionType": {
            "$ref": "#/components/schemas/VendorConnectionType"
          },
          "vendorConnectionRelationship": {
            "$ref": "#/components/schemas/VendorConnectionRelationship"
          },
          "vendorConnectionDetails": {
            "$ref": "#/components/schemas/VendorConnectionDetails"
          }
        },
        "description": "Single customer <-> vendor connection detected on an asset, with connection channel,\nrelationship class, and supporting details.\n\nIdentity model (TDR: AVD Data Pipeline for Titan, \"Data Model (3rd party)\"):\n  - The CUSTOMER side of the connection is taken from the enclosing RawObservation: typed\n    `RawObservation.asset` for the customer asset (e.g. the DNS hostname being scored), with\n    `RawObservation.organization_domain` as the customer organization.\n  - The VENDOR side is split into two layers on this message: typed `vendor_asset` for the\n    individual endpoint that justified the connection (the apex hostname / IP+port / URL the\n    producer extracted from the underlying evidence) and `vendor_organization_domain` for the\n    vendor's owning organization / scorecard apex when attribution is available.",
        "required": [
          "vendorOrganizationDomain",
          "vendorConnectionType",
          "vendorConnectionRelationship",
          "vendorConnectionDetails"
        ]
      },
      "EvidenceDomainSquatting": {
        "type": "object",
        "properties": {
          "typoSquattedDomain": {
            "type": "string"
          },
          "squattingEvidence": {
            "type": "string"
          },
          "algorithm": {
            "type": "string"
          },
          "method": {
            "type": "string"
          },
          "time": {
            "type": "string"
          }
        },
        "description": "Typosquat or lookalike domain finding: algorithm metadata, evidence string, and timing of detection.",
        "required": [
          "typoSquattedDomain",
          "squattingEvidence",
          "algorithm",
          "method",
          "time"
        ]
      },
      "EvidenceExploitedProduct": {
        "type": "object",
        "properties": {
          "productName": {
            "type": "string"
          },
          "serviceName": {
            "type": "string"
          },
          "cveId": {
            "type": "string"
          },
          "ransomwareName": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "productVersion": {
            "type": "string"
          },
          "banner": {
            "type": "string"
          }
        },
        "description": "Confirmed exploitation context: product, service, CVE, optional ransomware linkage, version, and banner proof.",
        "required": [
          "productName",
          "serviceName",
          "cveId",
          "ransomwareName",
          "productVersion",
          "banner"
        ]
      },
      "EvidenceHackerChatter": {
        "type": "object",
        "properties": {
          "eventDate": {
            "type": "string"
          },
          "evidence": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "language": {
            "type": "string"
          },
          "messages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "dataSource": {
            "type": "string"
          }
        },
        "description": "Underground or forum-style chatter: dated snippets, language, channel/source, and raw message excerpts.",
        "required": [
          "eventDate",
          "evidence",
          "language",
          "messages",
          "dataSource"
        ]
      },
      "EvidenceLeakedCredentialsV2": {
        "type": "object",
        "properties": {
          "ip": {
            "type": "string",
            "description": "IP address of the compromised host recorded in the stealer log."
          },
          "password": {
            "type": "string",
            "description": "Leaked password value extracted from the stealer log."
          },
          "infectionDate": {
            "type": "string",
            "description": "Date the stealer malware captured these credentials (ISO-8601 string)."
          },
          "userName": {
            "type": "string",
            "description": "Username or email address associated with the leaked credential."
          },
          "url": {
            "type": "string",
            "description": "Target URL or service for which the credential was captured."
          },
          "country": {
            "type": "string",
            "description": "Country of the compromised host at the time of infection."
          },
          "zipCode": {
            "type": "string",
            "description": "Postal code of the compromised host's reported location."
          },
          "location": {
            "type": "string",
            "description": "City or locality of the compromised host."
          },
          "currentLanguage": {
            "type": "string",
            "description": "System locale or UI language configured on the compromised host."
          },
          "os": {
            "type": "string",
            "description": "Operating system of the compromised host."
          },
          "stealerName": {
            "type": "string",
            "description": "Name of the stealer malware family that captured this credential."
          },
          "filename": {
            "type": "string",
            "description": "Log file or archive name from which this credential row was extracted."
          }
        },
        "description": "Stealer- or breach-derived credential row: user context, geo hints, stealer metadata, and exposure details.",
        "required": [
          "ip",
          "password",
          "infectionDate",
          "userName",
          "url",
          "country",
          "zipCode",
          "location",
          "currentLanguage",
          "os",
          "stealerName",
          "filename"
        ]
      },
      "EvidenceMalware": {
        "type": "object",
        "properties": {
          "family": {
            "type": "string"
          },
          "dstIp": {
            "type": "string"
          },
          "detectionMethods": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "observations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvidenceMalwareObservation"
            }
          },
          "userAgent": {
            "type": "string"
          }
        },
        "description": "Malware family and network observations aggregated with detection methods and optional user-agent context.",
        "required": [
          "family",
          "dstIp",
          "detectionMethods",
          "observations",
          "userAgent"
        ]
      },
      "EvidenceMalwareObservation": {
        "type": "object",
        "properties": {
          "srcIp": {
            "type": "string",
            "description": "IPv4 source address of the infected or C2-communicating host."
          },
          "srcPort": {
            "type": "integer",
            "format": "int64",
            "description": "Source port of the observed malicious connection."
          },
          "srcHost": {
            "type": "string",
            "description": "Hostname resolved for the source IP, if available."
          },
          "dstIp": {
            "type": "string",
            "description": "IPv4 destination address of the C2 server or targeted host."
          },
          "dstIpv6": {
            "type": "string",
            "description": "IPv6 destination address; reserved for future use.\n\nReserved for the future use."
          },
          "dstPort": {
            "type": "integer",
            "format": "int64",
            "description": "Destination port of the observed malicious connection."
          },
          "dstHost": {
            "type": "string",
            "description": "Hostname resolved for the destination IP, if available."
          },
          "protocol": {
            "type": "string",
            "description": "Transport protocol observed (e.g. \"TCP\", \"UDP\")."
          },
          "lastSeenAt": {
            "type": "string",
            "format": "date-time",
            "description": "When this network flow was last confirmed active."
          }
        },
        "description": "Single-flow malware sighting: endpoints, ports, protocol, and last-seen timestamp for aggregation into EvidenceMalware.",
        "required": [
          "srcIp",
          "srcPort",
          "srcHost",
          "dstIp",
          "dstIpv6",
          "dstPort",
          "dstHost",
          "protocol",
          "lastSeenAt"
        ]
      },
      "EvidenceOpenSSLVuln": {
        "type": "object",
        "properties": {
          "productName": {
            "type": "string"
          },
          "cveId": {
            "type": "string"
          },
          "userAgent": {
            "type": "string"
          },
          "banner": {
            "type": "string"
          }
        },
        "description": "OpenSSL-specific vulnerability signal: affected product, CVE, client fingerprint, and observed banner.",
        "required": [
          "productName",
          "cveId",
          "userAgent",
          "banner"
        ]
      },
      "EvidencePatchingAnalysis": {
        "type": "object",
        "properties": {
          "issueCount": {
            "type": "integer",
            "format": "int64",
            "description": "Total number of open vulnerability observations included in this analysis."
          },
          "resolvedIssues": {
            "type": "integer",
            "format": "int64",
            "description": "Number of observations that have been resolved."
          },
          "resolvedPerc": {
            "type": "integer",
            "format": "int64",
            "description": "Percentage of observations resolved (0–100)."
          },
          "timeToPatchAvg": {
            "type": "integer",
            "format": "int64",
            "description": "Average number of days taken to patch a vulnerability, across all resolved observations."
          },
          "range060": {
            "type": "integer",
            "format": "int64",
            "description": "Number of observations patched within 0–60 days of first detection."
          },
          "range61120": {
            "type": "integer",
            "format": "int64",
            "description": "Number of observations patched between 61 and 120 days of first detection."
          },
          "range121180": {
            "type": "integer",
            "format": "int64",
            "description": "Number of observations patched between 121 and 180 days of first detection."
          },
          "rangeOver180": {
            "type": "integer",
            "format": "int64",
            "description": "Number of observations still unpatched after more than 180 days."
          }
        },
        "description": "Patch velocity statistics for an organization: open vs resolved counts and age bucket histogram.",
        "required": [
          "issueCount",
          "resolvedIssues",
          "resolvedPerc",
          "timeToPatchAvg",
          "range060",
          "range61120",
          "range121180",
          "rangeOver180"
        ]
      },
      "EvidencePotentiallyVulnerable": {
        "type": "object",
        "properties": {
          "productName": {
            "type": "string"
          },
          "cveId": {
            "type": "string"
          },
          "banner": {
            "type": "string"
          }
        },
        "description": "Banner- or fingerprint-based hint that a product build may be affected by a CVE without confirmed exploitation.",
        "required": [
          "productName",
          "cveId",
          "banner"
        ]
      },
      "EvidenceProductObservation": {
        "type": "object",
        "properties": {
          "part": {
            "type": "string"
          },
          "vendor": {
            "type": "string"
          },
          "product": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "update": {
            "type": "string"
          },
          "edition": {
            "type": "string"
          },
          "language": {
            "type": "string"
          },
          "swEdition": {
            "type": "string"
          },
          "targetSw": {
            "type": "string"
          },
          "targetHw": {
            "type": "string"
          },
          "other": {
            "type": "string"
          }
        },
        "description": "Single CPE-style software component tuple (vendor/product/version facets) detected on an asset.",
        "required": [
          "part",
          "vendor",
          "product",
          "version",
          "update",
          "edition",
          "language",
          "swEdition",
          "targetSw",
          "targetHw",
          "other"
        ]
      },
      "EvidenceProductsDetected": {
        "type": "object",
        "properties": {
          "products": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvidenceProductObservation"
            }
          }
        },
        "description": "Full list of CPE component observations aggregated from a product-detection pass.",
        "required": [
          "products"
        ]
      },
      "EvidenceRansomwareAssociation": {
        "type": "object",
        "properties": {
          "services": {
            "type": "string"
          },
          "assets": {
            "type": "string"
          }
        },
        "description": "Summarizes services and assets tied to a ransomware correlation finding.",
        "required": [
          "services",
          "assets"
        ]
      },
      "EvidenceRansomwareVictim": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "Page title or listing heading as it appeared on the ransomware leak site."
          },
          "publishedDate": {
            "type": "string",
            "description": "Date the victim was listed on the leak site (ISO-8601 string)."
          },
          "leakUrl": {
            "type": "string",
            "description": "URL of the specific leak-site page or post referencing this victim."
          },
          "victimSite": {
            "type": "string",
            "description": "Primary domain of the victim organization as identified on the leak site."
          },
          "victimName": {
            "type": "string",
            "description": "Display name of the victim organization as listed by the threat actor."
          },
          "ransomwareName": {
            "type": "string",
            "description": "Name of the ransomware group or family that claimed this victim."
          },
          "year": {
            "type": "integer",
            "format": "int64",
            "description": "Calendar year the victim was listed; useful for trend analysis without parsing published_date."
          }
        },
        "description": "Ransomware leak-site style evidence: victim branding, leak URL, family, and publication timeline.",
        "required": [
          "title",
          "publishedDate",
          "leakUrl",
          "victimSite",
          "victimName",
          "ransomwareName",
          "year"
        ]
      },
      "EvidenceSPF": {
        "type": "object",
        "properties": {
          "record": {
            "type": "string"
          },
          "analysis": {
            "type": "string"
          },
          "explanation": {
            "type": "string"
          }
        },
        "description": "Parsed SPF/DMARC-related DNS record content with human-readable analysis and explanation.",
        "required": [
          "record",
          "analysis",
          "explanation"
        ]
      },
      "EvidenceSSH": {
        "type": "object",
        "properties": {
          "banner": {
            "type": "string"
          },
          "evidence": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "SSH service evidence: negotiated banner plus supporting proof strings from the scan.",
        "required": [
          "banner",
          "evidence"
        ]
      },
      "EvidenceService": {
        "type": "object",
        "properties": {
          "productName": {
            "type": "string"
          },
          "productVersion": {
            "type": "string"
          },
          "cloudProvider": {
            "type": "string"
          },
          "region": {
            "type": "string"
          },
          "banner": {
            "type": "string"
          }
        },
        "description": "Network listener or product fingerprint evidence (name, version, optional cloud/region, raw banner).",
        "required": [
          "productName",
          "productVersion",
          "banner"
        ]
      },
      "EvidenceServiceScan": {
        "type": "object",
        "properties": {
          "protocol": {
            "type": "string",
            "description": "Transport or application protocol detected on the port (e.g. \"http\", \"ssh\")."
          },
          "method": {
            "type": "string",
            "description": "Scan or probe method used to identify the service (e.g. \"SYN\", \"version\")."
          },
          "name": {
            "type": "string",
            "description": "Nmap service name matched for this port."
          },
          "product": {
            "type": "string",
            "description": "Identified product or software name (e.g. \"Apache httpd\", \"OpenSSH\")."
          },
          "version": {
            "type": "string",
            "description": "Detected version string of the product."
          },
          "tunnel": {
            "type": "string",
            "description": "Tunnel type wrapping the service, if any (e.g. \"ssl\")."
          },
          "serviceFp": {
            "type": "string",
            "description": "Raw service fingerprint string from the scanner."
          },
          "deviceType": {
            "type": "string",
            "description": "Device category inferred from the fingerprint (e.g. \"router\", \"printer\")."
          },
          "osType": {
            "type": "string",
            "description": "Operating system type inferred from the scan (e.g. \"Linux\", \"Windows\")."
          },
          "extraInfo": {
            "type": "string",
            "description": "Additional scan notes not captured by the structured fields above."
          },
          "httpHeader": {
            "type": "string",
            "description": "HTTP response headers captured during the version probe, if applicable."
          },
          "refinedNames": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Canonical service names after post-processing or normalization."
          },
          "cpes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "CPE strings identifying the software stack detected on this service."
          },
          "vulnersCpes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "CPE strings used specifically by the Vulners vulnerability correlation feed."
          },
          "banners": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Raw banner strings returned by the service during the scan."
          }
        },
        "description": "Rich Nmap-style service fingerprint: protocol stack, CPE guesses, banners, and HTTP headers.",
        "required": [
          "protocol",
          "method",
          "name",
          "product",
          "version",
          "tunnel",
          "serviceFp",
          "deviceType",
          "osType",
          "extraInfo",
          "httpHeader",
          "refinedNames",
          "cpes",
          "vulnersCpes",
          "banners"
        ]
      },
      "EvidenceSkynet": {
        "type": "object",
        "properties": {
          "region": {
            "type": "string"
          },
          "affectedProduct": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "attackTarget": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "extra": {
            "type": "string"
          }
        },
        "description": "Skynet-style regional threat context: affected products, attack targets, and supplemental notes.",
        "required": [
          "region",
          "affectedProduct",
          "attackTarget",
          "extra"
        ]
      },
      "EvidenceSynthHighRiskAppsecAccess": {
        "type": "object",
        "properties": {
          "domains": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "Synthetic high-risk app-sec signal listing domains that imply dangerous external exposure.",
        "required": [
          "domains"
        ]
      },
      "EvidenceSynthPossibleInitialAccess": {
        "type": "object",
        "properties": {
          "observations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvidenceSynthPossibleInitialAccessObservation"
            }
          }
        },
        "description": "Aggregated synthetic initial-access hypothesis built from repeated endpoint observations.",
        "required": [
          "observations"
        ]
      },
      "EvidenceSynthPossibleInitialAccessObservation": {
        "type": "object",
        "properties": {
          "ip": {
            "type": "string"
          },
          "port": {
            "type": "integer",
            "format": "int64"
          },
          "service": {
            "type": "string"
          }
        },
        "description": "One network endpoint contributing to a synthetic “possible initial access” story (IP, port, service label).",
        "required": [
          "ip",
          "port",
          "service"
        ]
      },
      "EvidenceTLS": {
        "type": "object",
        "properties": {
          "observations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvidenceTLSObservation"
            }
          }
        },
        "description": "Rolled-up TLS evidence across multiple observations of the same logical finding.",
        "required": [
          "observations"
        ]
      },
      "EvidenceTLSObservation": {
        "type": "object",
        "properties": {
          "ip": {
            "type": "string"
          },
          "ipv6": {
            "type": "string",
            "description": "Reserved for the future use."
          },
          "sni": {
            "type": "string"
          },
          "evidence": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "lastSeenAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "TLS handshake or certificate sighting at a specific IP/SNI with textual proof and last seen time.",
        "required": [
          "ip",
          "ipv6",
          "sni",
          "evidence",
          "lastSeenAt"
        ]
      },
      "EvidenceTorExitNode": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          },
          "evidence": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "userAgent": {
            "type": "string"
          }
        },
        "description": "Tor exit-node usage evidence: source URL, supporting strings, and client user agent when available.",
        "required": [
          "url",
          "evidence",
          "userAgent"
        ]
      },
      "EvidenceVulnerability": {
        "type": "object",
        "properties": {
          "cveId": {
            "type": "string"
          }
        },
        "description": "Minimal CVE-focused evidence when the observation is driven by a single vulnerability identifier.",
        "required": [
          "cveId"
        ]
      },
      "EvidenceX509": {
        "type": "object",
        "properties": {
          "sha256Fingerprint": {
            "type": "string"
          },
          "serialNumber": {
            "type": "string"
          },
          "issuerName": {
            "type": "string"
          },
          "observations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EvidenceX509Observation"
            }
          },
          "evidence": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "Certificate material and observations: fingerprint, serial, issuer, repeated sightings, and proof strings.",
        "required": [
          "sha256Fingerprint",
          "serialNumber",
          "issuerName",
          "observations",
          "evidence"
        ]
      },
      "EvidenceX509Observation": {
        "type": "object",
        "properties": {
          "ip": {
            "type": "string"
          },
          "ipv6": {
            "type": "string",
            "description": "Reserved for the future use."
          },
          "port": {
            "type": "integer",
            "format": "int64"
          },
          "sni": {
            "type": "string"
          },
          "lastSeenAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "Single X.509 presentation on the wire: IP, port, optional SNI, and when the cert was last observed.",
        "required": [
          "ip",
          "ipv6",
          "port",
          "sni",
          "lastSeenAt"
        ]
      },
      "File": {
        "type": "object",
        "properties": {
          "orn": {
            "type": "string",
            "description": "ORN identifying this attachment within the platform."
          },
          "name": {
            "type": "string",
            "description": "Original filename as uploaded by the user."
          },
          "url": {
            "type": "string",
            "description": "Pre-signed or permanent URL from which the file can be downloaded."
          },
          "size": {
            "type": "integer",
            "format": "int64",
            "description": "File size in bytes."
          }
        },
        "title": "/ File class",
        "required": [
          "orn",
          "name",
          "url",
          "size"
        ]
      },
      "FilterComparison": {
        "type": "string",
        "enum": [
          "COMPARISON_UNSPECIFIED",
          "COMPARISON_EQ",
          "COMPARISON_NEQ",
          "COMPARISON_GT",
          "COMPARISON_GTE",
          "COMPARISON_LT",
          "COMPARISON_LTE",
          "COMPARISON_BETWEEN",
          "COMPARISON_CONTAINS"
        ],
        "default": "COMPARISON_UNSPECIFIED",
        "description": "Predicate operators for comparing a field to one or more literal values (equality, range, substring).\n\n - COMPARISON_GT: Greater than\n - COMPARISON_GTE: Greater than or equal\n - COMPARISON_LT: Less than\n - COMPARISON_LTE: Less than or equal\n - COMPARISON_BETWEEN: Between two values (inclusive range)\n - COMPARISON_CONTAINS: Contains substring (case-insensitive)"
      },
      "FilterOperator": {
        "type": "string",
        "enum": [
          "OPERATOR_UNSPECIFIED",
          "OPERATOR_AND",
          "OPERATOR_OR"
        ],
        "default": "OPERATOR_UNSPECIFIED",
        "description": "Boolean combiner for nested filter lists (match all vs match any)."
      },
      "FilterOptionValue": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "value": {
            "$ref": "#/components/schemas/FilterValue"
          }
        },
        "description": "One labeled choice in a filter dropdown, carrying the encoded value clients send back.",
        "required": [
          "label",
          "value"
        ]
      },
      "FilterRangeBounds": {
        "type": "object",
        "properties": {
          "numberBounds": {
            "$ref": "#/components/schemas/NumberRangeBounds"
          },
          "dateBounds": {
            "$ref": "#/components/schemas/DateRangeBounds"
          }
        },
        "description": "Min/max boundaries for a range filter, either numeric or date-based."
      },
      "FilterValue": {
        "type": "object",
        "properties": {
          "stringValue": {
            "type": "string"
          },
          "numberValue": {
            "type": "number",
            "format": "double"
          },
          "boolValue": {
            "type": "boolean"
          },
          "stringListValue": {
            "$ref": "#/components/schemas/StringList"
          },
          "numberRangeValue": {
            "$ref": "#/components/schemas/NumberRange"
          },
          "dateRangeValue": {
            "$ref": "#/components/schemas/DateRange"
          },
          "dateValue": {
            "type": "string",
            "format": "date-time"
          }
        },
        "description": "Holds the right-hand operand of a filter comparison."
      },
      "FlagObservationsRequest": {
        "type": "object",
        "properties": {
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicFilter"
            },
            "description": "Filter expressions identifying the observations to flag. Used when observation_orns\nis empty; ignored when observation_orns is non-empty."
          },
          "observationOrns": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Explicit ORNs (format: `orn:<version>:observation:<view>:<key>:<view-owner-domain>`) of the\nobservations to flag. When non-empty, the server flags exactly these observations and\nignores `filters`. When empty, the server falls back to selecting observations via `filters`."
          }
        },
        "description": "Identifies observations to flag using either an explicit ORN list or filter expressions.",
        "required": [
          "filters",
          "observationOrns"
        ]
      },
      "FlagObservationsResponse": {
        "type": "object",
        "properties": {
          "flaggedCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of observations that were newly flagged by this request."
          },
          "alreadyFlaggedCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of observations that were already flagged before this request."
          }
        },
        "description": "Observation-level flagging result: how many were newly flagged vs already flagged.",
        "required": [
          "flaggedCount",
          "alreadyFlaggedCount"
        ]
      },
      "GetFilterOptionValuesResponse": {
        "type": "object",
        "properties": {
          "field": {
            "$ref": "#/components/schemas/PublicFilterableField"
          },
          "fieldValues": {
            "$ref": "#/components/schemas/DiscreteFilterValues"
          },
          "totalCount": {
            "type": "integer",
            "format": "int32",
            "description": "Total number of values available for the field (before pagination)."
          }
        },
        "description": "The discrete values available for the requested field, with a total count for pagination.",
        "required": [
          "field",
          "fieldValues",
          "totalCount"
        ]
      },
      "GetFourthPartiesRequest": {
        "type": "object",
        "properties": {
          "sortField": {
            "type": "string",
            "description": "Field name to sort results by."
          },
          "sortOrder": {
            "$ref": "#/components/schemas/SortOrder"
          },
          "limit": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum number of items to return per page."
          },
          "offset": {
            "type": "integer",
            "format": "int32",
            "description": "Zero-based offset for page-based pagination."
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicAvdFilter"
            },
            "description": "Filter expressions applied to narrow the result set."
          },
          "includeFilterOptions": {
            "type": "boolean",
            "description": "When true, the response includes available filter option values for the current result set."
          },
          "vendor": {
            "type": "string",
            "description": "When set, restricts results to connections originating from this portfolio vendor display name."
          },
          "fourthParty": {
            "type": "string",
            "description": "When set, restricts results to connections pointing at this fourth-party display name."
          },
          "isMonitored": {
            "type": "boolean",
            "description": "When set, restricts results to pairs where the fourth party is (true) or is not (false) directly monitored."
          }
        },
        "description": "Pagination, sort, filters, and optional scoping for the flat fourth-party relationship list.",
        "required": [
          "filters"
        ]
      },
      "GetFourthPartiesResponse": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicFourthPartyRelationshipItem"
            },
            "description": "One entry per (portfolio vendor, fourth-party domain) pair."
          },
          "totalCount": {
            "type": "integer",
            "format": "int32",
            "description": "Total number of pairs matching the request filters, before pagination."
          },
          "filterOptions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicAvdFilterOption"
            },
            "description": "Filter option values available for the current result set; populated when include_filter_options is true."
          }
        },
        "description": "Paginated fourth-party relationship rows with optional filter options.",
        "required": [
          "items",
          "totalCount",
          "filterOptions"
        ]
      },
      "GetFourthPartyGroupsRequest": {
        "type": "object",
        "properties": {
          "sortField": {
            "type": "string",
            "description": "Field name to sort results by (e.g. \"connected_vendor_count\")."
          },
          "sortOrder": {
            "$ref": "#/components/schemas/SortOrder"
          },
          "limit": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum number of items to return per page."
          },
          "offset": {
            "type": "integer",
            "format": "int32",
            "description": "Zero-based offset for page-based pagination."
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicAvdFilter"
            },
            "description": "Filter expressions applied to narrow the result set."
          },
          "includeFilterOptions": {
            "type": "boolean",
            "description": "When true, the response includes available filter option values for the current result set."
          }
        },
        "description": "Pagination, sort, and filters for the grouped fourth-party list.",
        "required": [
          "filters"
        ]
      },
      "GetFourthPartyGroupsResponse": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicFourthPartyGroupItem"
            },
            "description": "One entry per distinct fourth-party domain observed across the portfolio."
          },
          "totalCount": {
            "type": "integer",
            "format": "int32",
            "description": "Total number of distinct fourth-party domains matching the request filters, before pagination."
          },
          "filterOptions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicAvdFilterOption"
            },
            "description": "Filter option values available for the current result set; populated when include_filter_options is true."
          }
        },
        "description": "Paginated grouped fourth-party rows with optional filter options.",
        "required": [
          "items",
          "totalCount",
          "filterOptions"
        ]
      },
      "GetFourthPartyVendorsRequest": {
        "type": "object",
        "properties": {
          "fourthParty": {
            "type": "string",
            "description": "Display name of the fourth party whose connected portfolio vendors are requested."
          },
          "sortField": {
            "type": "string",
            "description": "Field name to sort results by."
          },
          "sortOrder": {
            "$ref": "#/components/schemas/SortOrder"
          },
          "limit": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum number of items to return per page."
          },
          "offset": {
            "type": "integer",
            "format": "int32",
            "description": "Zero-based offset for page-based pagination."
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicAvdFilter"
            },
            "description": "Filter expressions applied to narrow the result set."
          },
          "includeFilterOptions": {
            "type": "boolean",
            "description": "When true, the response includes available filter option values for the current result set."
          }
        },
        "description": "Identifies the fourth party to drill into, plus pagination, sort, and filters.",
        "required": [
          "fourthParty",
          "filters"
        ]
      },
      "GetFourthPartyVendorsResponse": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicFourthPartyVendorItem"
            },
            "description": "One entry per portfolio vendor with at least one connection to the requested fourth party."
          },
          "totalCount": {
            "type": "integer",
            "format": "int32",
            "description": "Total number of portfolio vendors connected to the requested fourth party, before pagination."
          },
          "filterOptions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicAvdFilterOption"
            },
            "description": "Filter option values available for the current result set; populated when include_filter_options is true."
          }
        },
        "description": "Paginated portfolio vendors connecting to the requested fourth party, with optional filter options.",
        "required": [
          "items",
          "totalCount",
          "filterOptions"
        ]
      },
      "GetImpactedCompaniesRequest": {
        "type": "object",
        "properties": {
          "orgDomain": {
            "type": "string",
            "description": "Domain of the organization the security event belongs to."
          },
          "eventId": {
            "type": "string",
            "description": "Unique identifier of the security event."
          },
          "limit": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum rows to return. When unset, the server defaults to 10."
          },
          "offset": {
            "type": "integer",
            "format": "int32",
            "description": "Zero-based offset into the full list. When unset, defaults to 0."
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicSecurityEventFilter"
            },
            "description": "Filter expressions applied to the impacted-company rows. For tab filtering,\nuse SECURITY_EVENTS_FIELD_IMPACT_REASONING with COMPARISON_EQ and a list value."
          },
          "sortField": {
            "type": "string",
            "description": "Sort key for the returned rows. When unset, the server defaults to impact_reasoning then organization domain."
          },
          "sortOrder": {
            "$ref": "#/components/schemas/SortOrder"
          }
        },
        "description": "Keys, pagination, filters, and sort for listing companies impacted by one security event.",
        "required": [
          "orgDomain",
          "eventId",
          "filters"
        ]
      },
      "GetImpactedCompaniesResponse": {
        "type": "object",
        "properties": {
          "impactedCompanies": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SecurityEventImpactedCompany"
            },
            "description": "Companies impacted by the security event, matching the request filters and pagination."
          },
          "totalCount": {
            "type": "integer",
            "format": "int32",
            "description": "Total rows matching the applied filters, before pagination."
          },
          "namedVictimsCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of named victims (impact_reasoning in VICTIM_ENTITY or NAMED_VICTIM).\nEvent-wide; not affected by the applied filters."
          },
          "detectedConnectionsCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of companies with impact_reasoning CONNECTION_DETECTED.\nEvent-wide; not affected by the applied filters."
          },
          "impactedCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of companies confirmed impacted. Event-wide; not affected by the applied filters."
          },
          "notImpactedCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of companies confirmed not impacted. Event-wide; not affected by the applied filters."
          },
          "impactedUnknownCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of companies whose impacted status is unknown. Event-wide; not affected by the applied filters."
          },
          "lastActivityDate": {
            "type": "string",
            "format": "date-time",
            "description": "Most recent activity across all impacted companies for this event; absent\nwhen no activity has been recorded yet."
          }
        },
        "description": "Summary counts plus paginated rows of companies impacted by a security event.",
        "required": [
          "impactedCompanies",
          "totalCount",
          "namedVictimsCount",
          "detectedConnectionsCount",
          "impactedCount",
          "notImpactedCount",
          "impactedUnknownCount"
        ]
      },
      "GetObservationByOrnResponse": {
        "type": "object",
        "properties": {
          "observation": {
            "$ref": "#/components/schemas/Observation"
          }
        },
        "description": "A single observation record identified by its ORN.",
        "required": [
          "observation"
        ]
      },
      "GetObservationGroupsRequest": {
        "type": "object",
        "properties": {
          "sortField": {
            "type": "string",
            "description": "Field name to sort results by."
          },
          "sortOrder": {
            "$ref": "#/components/schemas/SortOrder"
          },
          "limit": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum number of observation groups to return per page."
          },
          "offset": {
            "type": "integer",
            "format": "int32",
            "description": "Zero-based offset for page-based pagination."
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicFilter"
            },
            "description": "Filter expressions applied to narrow the result set."
          },
          "includeFilterOptions": {
            "type": "boolean",
            "description": "When true, the response includes available filter option values for the current result set."
          },
          "queryMode": {
            "$ref": "#/components/schemas/ObservationsQueryMode"
          }
        },
        "description": "Pagination, filters, and open/resolved mode for listing observation groups on the public API.\nView (VRM vs self) is determined server-side from the caller's entitlement and is not a request input.",
        "required": [
          "filters",
          "queryMode"
        ]
      },
      "GetObservationGroupsResponse": {
        "type": "object",
        "properties": {
          "observationGroups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ObservationGroup"
            },
            "description": "The observation groups matching the request filters."
          },
          "totalCount": {
            "type": "integer",
            "format": "int32",
            "description": "Total number of observation groups matching the query (before pagination)."
          },
          "filterOptions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicFilterOption"
            },
            "description": "Filter option values available for the current result set; populated when include_filter_options is true."
          }
        },
        "description": "Paginated observation groups matching the request filters, with optional filter options.",
        "required": [
          "observationGroups",
          "totalCount",
          "filterOptions"
        ]
      },
      "GetObservationsRequest": {
        "type": "object",
        "properties": {
          "sortField": {
            "type": "string",
            "description": "Field name to sort results by."
          },
          "sortOrder": {
            "$ref": "#/components/schemas/SortOrder"
          },
          "limit": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum number of observations to return per page."
          },
          "offset": {
            "type": "integer",
            "format": "int32",
            "description": "Zero-based offset for page-based pagination; ignored when cursor is provided."
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicFilter"
            },
            "description": "Filter expressions applied to narrow the result set."
          },
          "includeFilterOptions": {
            "type": "boolean",
            "description": "When true, the response includes available filter option values for the current result set."
          },
          "queryMode": {
            "$ref": "#/components/schemas/ObservationsQueryMode"
          },
          "cursor": {
            "type": "string",
            "description": "Opaque cursor for keyset pagination. Set to \"\" to request the first page;\nomit (leave unset) to use offset-based pagination instead."
          },
          "observationGroupOrn": {
            "type": "string",
            "title": "ORN identifying an observation group (format: `orn:<version>:observation:group:<key>:<view-owner-domain>`).\nWhen provided, the server narrows results to observations in that group by appending an\ninternal filter on the observation name key derived from the ORN"
          }
        },
        "description": "Pagination, filters, and open/resolved mode for listing observations on the public API.\nView (VRM vs self) is determined server-side from the caller's entitlement and is not a request input.",
        "required": [
          "filters",
          "queryMode"
        ]
      },
      "GetObservationsResponse": {
        "type": "object",
        "properties": {
          "observations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Observation"
            },
            "description": "The observations matching the request filters and group."
          },
          "totalCount": {
            "type": "integer",
            "format": "int32",
            "description": "Total number of observations matching the query (before pagination)."
          },
          "filterOptions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicFilterOption"
            },
            "description": "Filter option values available for the current result set; populated when include_filter_options is true."
          },
          "nextCursor": {
            "type": "string",
            "description": "Opaque cursor to pass as cursor in the next request. Absent when no further pages exist."
          }
        },
        "description": "Paginated observations matching the request filters, with optional filter options and a cursor for subsequent pages.",
        "required": [
          "observations",
          "totalCount",
          "filterOptions"
        ]
      },
      "GetQuestionnaireResponse": {
        "type": "object",
        "properties": {
          "questionnaire": {
            "$ref": "#/components/schemas/Questionnaire"
          }
        },
        "description": "Response containing the requested questionnaire.",
        "required": [
          "questionnaire"
        ]
      },
      "GetQuestionnaireTemplateResponse": {
        "type": "object",
        "properties": {
          "template": {
            "$ref": "#/components/schemas/QuestionnaireTemplate"
          }
        },
        "description": "Response containing the requested questionnaire template.",
        "required": [
          "template"
        ]
      },
      "GetSecurityEventActionsRequest": {
        "type": "object",
        "properties": {
          "orgDomain": {
            "type": "string",
            "description": "Domain of the organization the security event belongs to."
          },
          "eventId": {
            "type": "string",
            "description": "Unique identifier of the security event."
          },
          "vendorDomain": {
            "type": "string",
            "description": "Domain of the vendor whose action thread is being requested. Required when the\ncaller is resolved to the VRM view."
          },
          "vrmDomain": {
            "type": "string",
            "description": "Domain of the VRM organization whose action thread is being requested. Required\nwhen the caller is resolved to the vendor (self) view."
          }
        },
        "description": "Keys for fetching a vendor's action feed on a security event. Exactly one of\nvendor_domain/vrm_domain is required, depending on the server-resolved view: a\nVRM-entitled caller must supply vendor_domain (which of its monitored vendors);\na non-VRM caller (self/vendor view) must supply vrm_domain (which VRM counterparty).",
        "required": [
          "orgDomain",
          "eventId"
        ]
      },
      "GetSecurityEventActionsResponse": {
        "type": "object",
        "properties": {
          "entries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SecurityEventActivityEntry"
            },
            "description": "Action entries in descending order by event time (most recent first). Not\npaginated: bounded by one vendor's workflow activity on one event, the same\nscope and cardinality as SecurityEventVendorDetail.communication_log, which\nreturns the same SecurityEventActivityEntry type unpaginated for the same\nreason. Revisit if this proves unbounded in practice before promoting past\nthe current `internal` stability."
          }
        },
        "description": "Chronological action feed for a vendor on a security event, newest first.",
        "required": [
          "entries"
        ]
      },
      "GetSecurityEventResponse": {
        "type": "object",
        "properties": {
          "event": {
            "$ref": "#/components/schemas/SecurityEvent"
          }
        },
        "description": "Single security event matching the requested keys.",
        "required": [
          "event"
        ]
      },
      "GetSecurityEventsFeedRequest": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum number of security events to return per page. When unset, the server defaults to 10."
          },
          "offset": {
            "type": "integer",
            "format": "int32",
            "description": "Zero-based offset for page-based pagination. When unset, defaults to 0."
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicSecurityEventFilter"
            },
            "description": "Filter expressions applied to narrow the result set."
          },
          "sortField": {
            "type": "string",
            "description": "Field name to sort results by (supports last_updated, first_detected, event_date)."
          },
          "sortOrder": {
            "$ref": "#/components/schemas/SortOrder"
          },
          "view": {
            "$ref": "#/components/schemas/SecurityEventView"
          }
        },
        "description": "Pagination, filters, and sort for listing security events on the public API.\nView (VRM vs vendor) defaults to VRM when unset.",
        "required": [
          "filters"
        ]
      },
      "GetSecurityEventsFeedResponse": {
        "type": "object",
        "properties": {
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SecurityEventSummary"
            },
            "description": "One page of feed rows in server sort order (may be empty)."
          },
          "totalCount": {
            "type": "integer",
            "format": "int32",
            "description": "Total events matching the request filters, before pagination."
          }
        },
        "description": "Paginated security events matching the request filters, with the total count\nmatching the query before pagination. An empty events list with total_count\nof zero is valid when no rows match.",
        "required": [
          "events",
          "totalCount"
        ]
      },
      "GetVendorPortfoliosResponse": {
        "type": "object",
        "properties": {
          "portfolios": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VendorPortfolio"
            },
            "description": "Active, non-watchlist portfolios the vendor belongs to, on this page."
          },
          "totalCount": {
            "type": "integer",
            "format": "int32",
            "description": "Total number of matching portfolios (before pagination)."
          },
          "nextCursor": {
            "type": "string",
            "description": "Opaque cursor to pass as cursor in the next request. Absent when no further\npages exist."
          }
        },
        "description": "A page of the vendor's portfolios, with paging metadata.",
        "required": [
          "portfolios",
          "totalCount"
        ]
      },
      "GetVendorResponse": {
        "type": "object",
        "properties": {
          "vendor": {
            "$ref": "#/components/schemas/vendor.v1.Vendor"
          }
        },
        "description": "Response containing the requested vendor.",
        "required": [
          "vendor"
        ]
      },
      "GetVendorScoresRequest": {
        "type": "object",
        "properties": {
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicFilter"
            },
            "description": "Filter selecting which vendor domain(s) to return scores for (required; VENDOR field only)."
          }
        },
        "description": "Selects one or more vendor domains to fetch scores for. Only a VENDOR field filter is\nsupported (EQ for a single domain, or an IN-style string_list_value for a batch); any other\nfilter field is rejected with INVALID_ARGUMENT. VRM entitlement per domain, and the domain\ncount limit, are enforced server-side — not part of this request shape.",
        "required": [
          "filters"
        ]
      },
      "GetVendorScoresResponse": {
        "type": "object",
        "properties": {
          "vendorScores": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VendorScoreResult"
            },
            "description": "One score result per requested domain the caller is entitled to see; requested domains\nthat are absent were not found or not VRM-entitled (indistinguishable by design)."
          }
        },
        "description": "Scores for every requested domain the caller is entitled to see. A domain that was requested\nbut omitted from the response was either not found or not VRM-entitled — the two are\nindistinguishable by design, so this response shape cannot be used as an entitlement oracle.",
        "required": [
          "vendorScores"
        ]
      },
      "GetVendorSecurityEventDetailResponse": {
        "type": "object",
        "properties": {
          "vendorDetail": {
            "$ref": "#/components/schemas/SecurityEventVendorDetail"
          }
        },
        "description": "Vendor detail payload for a single vendor on a security event.",
        "required": [
          "vendorDetail"
        ]
      },
      "GetVendorSummaryRequest": {
        "type": "object",
        "properties": {
          "vendorDomain": {
            "type": "string",
            "description": "Registered domain of the vendor to look up."
          },
          "rangeDays": {
            "type": "integer",
            "format": "int32",
            "description": "Lookback window in days used to compute company_connection_count_change; defaults to 30 when unset."
          }
        },
        "description": "Identifies the vendor to summarize and the lookback window for change counts.",
        "required": [
          "vendorDomain"
        ]
      },
      "GetVendorSummaryResponse": {
        "type": "object",
        "properties": {
          "isFourthParty": {
            "type": "boolean",
            "description": "True when this vendor appears as a fourth party in the caller organization's portfolio AVD data."
          },
          "companyConnectionCount": {
            "type": "integer",
            "format": "int32",
            "description": "Total distinct companies this vendor connects to across the full AVD dataset —\na global vendor-footprint metric, not limited to the caller's organization or portfolio."
          },
          "companyConnectionCountChange": {
            "type": "integer",
            "format": "int32",
            "description": "Net change in company_connection_count over the request's range_days window (can be negative)."
          },
          "companyConnectionCountAdded": {
            "type": "integer",
            "format": "int32",
            "description": "Active connections first observed within the request's range_days window (the \"+N new\" additions)."
          },
          "monitoredCompanyConnectionCount": {
            "type": "integer",
            "format": "int32",
            "description": "Of company_connection_count, connections to companies directly monitored by the caller's organization."
          },
          "unmonitoredCompanyConnectionCount": {
            "type": "integer",
            "format": "int32",
            "description": "Of company_connection_count, connections to companies not monitored by the caller's organization."
          }
        },
        "description": "Fourth-party status and company-connection counts for the requested vendor domain.",
        "required": [
          "isFourthParty",
          "companyConnectionCount",
          "companyConnectionCountChange"
        ]
      },
      "ListAuditLogsResponse": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicAuditLogEvent"
            }
          },
          "nextCursor": {
            "type": "string",
            "description": "Absent on the last page."
          }
        },
        "description": "A page of audit events, newest first. There is no total count.",
        "required": [
          "items"
        ]
      },
      "ListQuestionnaireTemplatesResponse": {
        "type": "object",
        "properties": {
          "templates": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QuestionnaireTemplate"
            },
            "description": "The templates visible to the caller, curated for public consumption."
          },
          "totalCount": {
            "type": "integer",
            "format": "int32",
            "description": "Total number of templates visible to the caller (before pagination)."
          },
          "nextCursor": {
            "type": "string",
            "description": "Opaque cursor to pass as cursor in the next request. Absent when no further\npages exist."
          }
        },
        "description": "A page of questionnaire templates visible to the caller's organization, with\npaging metadata.",
        "required": [
          "templates",
          "totalCount"
        ]
      },
      "ListVendorGroupsResponse": {
        "type": "object",
        "properties": {
          "vendorGroups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VendorGroup"
            },
            "description": "The vendor groups on this page, curated for public consumption, newest first."
          },
          "totalCount": {
            "type": "integer",
            "format": "int32",
            "description": "Total number of groups in the caller's organization (before pagination)."
          },
          "nextCursor": {
            "type": "string",
            "description": "Opaque cursor to pass as cursor in the next request. Absent when no further\npages exist, which is the caller's signal to stop paging."
          }
        },
        "description": "A page of vendor groups from the caller's directory, with paging metadata.",
        "required": [
          "vendorGroups",
          "totalCount"
        ]
      },
      "ListVendorsRequest": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "format": "int32",
            "description": "Maximum number of vendors to return per page. Bounded server-side: values\nabove the server maximum are clamped, and an unset or zero value uses a\nserver default. Must not be negative."
          },
          "offset": {
            "type": "integer",
            "format": "int32",
            "description": "Zero-based offset for page-based pagination; ignored when cursor is\nprovided. Must not be negative."
          },
          "cursor": {
            "type": "string",
            "description": "Opaque pagination cursor, echoed from a prior response's next_cursor.\nSet to \"\" or leave unset to request the first page."
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicVendorFilter"
            },
            "description": "Filter expressions applied to narrow the result set. Only the fields and\noperators in PublicVendorsFilterableField are accepted; anything else, or a\ntree that exceeds the server's complexity limits, is rejected with\nINVALID_ARGUMENT."
          },
          "includeFilterOptions": {
            "type": "boolean",
            "description": "When true, the response includes the available filter option values for the\ncaller's directory in filter_options."
          }
        },
        "description": "Pagination inputs for listing vendors from the caller's directory.\nOrganization scope is derived from the access token, not from this message.",
        "required": [
          "filters"
        ]
      },
      "ListVendorsResponse": {
        "type": "object",
        "properties": {
          "vendors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/vendor.v1.Vendor"
            },
            "description": "The vendors on this page, curated for public consumption."
          },
          "totalCount": {
            "type": "integer",
            "format": "int32",
            "description": "Total number of vendors in the caller's directory (before pagination)."
          },
          "nextCursor": {
            "type": "string",
            "description": "Opaque cursor to pass as cursor in the next request. Absent when no further\npages exist."
          },
          "filterOptions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicVendorFilterOption"
            },
            "description": "Filter option values available for the caller's directory; populated when\ninclude_filter_options is true."
          }
        },
        "description": "A page of vendors from the caller's directory, with paging metadata.",
        "required": [
          "vendors",
          "totalCount",
          "filterOptions"
        ]
      },
      "NumberRange": {
        "type": "object",
        "properties": {
          "min": {
            "type": "number",
            "format": "double",
            "title": "Inclusive"
          },
          "max": {
            "type": "number",
            "format": "double",
            "title": "Inclusive"
          }
        },
        "description": "Numeric closed interval used for BETWEEN or bounded comparisons on metrics."
      },
      "NumberRangeBounds": {
        "type": "object",
        "properties": {
          "minValue": {
            "type": "number",
            "format": "double",
            "title": "Minimum allowable value (inclusive)"
          },
          "maxValue": {
            "type": "number",
            "format": "double",
            "title": "Maximum allowable value (inclusive)"
          }
        },
        "description": "Minimum and maximum numeric values permitted when constraining a filter."
      },
      "Observation": {
        "type": "object",
        "properties": {
          "observationCategory": {
            "$ref": "#/components/schemas/ObservationCategory"
          },
          "observationType": {
            "$ref": "#/components/schemas/ObservationType"
          },
          "observationGroupIdentifier": {
            "type": "string",
            "title": "This can be CVE ID or any other identifier that can uniquely identify an observation group with the category and type"
          },
          "ownerOrganizationOrn": {
            "type": "string",
            "title": "`orn:<version>:organization:<top-level domain>`"
          },
          "observationGroupOrn": {
            "type": "string",
            "title": "`orn:<version>:observation:group:[<OBSERVATION_CATEGORY>:<OBSERVATION_TYPE>:CVE-1234-567]:<top-level domain>`"
          },
          "observationOrn": {
            "type": "string",
            "title": "`orn:<version>:observation:[<OBSERVATION_CATEGORY>:<OBSERVATION_TYPE>:CVE-1234-567]:[<ASSET_TYPE_IP_PORT:<address>:<port>:<protocol> | ASSET_TYPE_URL:<url> | ASSET_TYPE_DNS:<dns_type>:<domain>>]:<top-level domain>`"
          },
          "assetName": {
            "type": "string",
            "title": "display name which is either ip, url or domain"
          },
          "assetType": {
            "$ref": "#/components/schemas/AssetType"
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time"
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time",
            "title": "(ai-generated)"
          },
          "ipAndPort": {
            "$ref": "#/components/schemas/AssetIpPort"
          },
          "url": {
            "$ref": "#/components/schemas/AssetUrl"
          },
          "dns": {
            "$ref": "#/components/schemas/AssetDns"
          },
          "severity": {
            "$ref": "#/components/schemas/ObservationSeverity"
          },
          "evidence": {
            "$ref": "#/components/schemas/Evidence"
          },
          "impact": {
            "$ref": "#/components/schemas/ObservationImpact"
          },
          "remediationStatus": {
            "$ref": "#/components/schemas/RemediationStatus"
          },
          "approvalStatus": {
            "$ref": "#/components/schemas/ApprovalStatus"
          },
          "vendor": {
            "$ref": "#/components/schemas/observation.v1.Vendor"
          },
          "requestors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Requestor"
            },
            "title": "only in Vendor view"
          },
          "requestorsCount": {
            "type": "integer",
            "format": "int32",
            "title": "only in Vendor view"
          },
          "message": {
            "type": "string",
            "title": "The latest remediation action message if available"
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/File"
            }
          },
          "flagged": {
            "type": "boolean",
            "title": "only in VRM view"
          },
          "resolvedAt": {
            "type": "string",
            "format": "date-time",
            "title": "only in VRM Resolved view"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "vendorDisplayName": {
            "type": "string",
            "title": "vendor display name"
          },
          "vendorLogoIcon": {
            "type": "string",
            "title": "vendor logo icon"
          },
          "portfolioIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "title": "portfolio ids"
          },
          "cve": {
            "$ref": "#/components/schemas/VulnerabilityDetail"
          },
          "name": {
            "type": "string",
            "title": "user friendly display name for the observation"
          },
          "observationDetails": {
            "$ref": "#/components/schemas/ObservationDetails"
          },
          "observationStatus": {
            "$ref": "#/components/schemas/ObservationStatus"
          }
        },
        "title": "/ Observation class\n/ Represents an individual observation on a single asset\n/ Designed to unify DNS hostname, URL, (IP, port, proto) tuple\n/ Also contains the evidence because evidence is always tied to an observation",
        "required": [
          "observationCategory",
          "observationType",
          "observationGroupIdentifier",
          "ownerOrganizationOrn",
          "observationGroupOrn",
          "observationOrn",
          "assetName",
          "assetType",
          "firstSeen",
          "lastSeen",
          "severity",
          "evidence",
          "remediationStatus",
          "requestors",
          "attachments",
          "portfolioIds",
          "name",
          "observationStatus"
        ]
      },
      "ObservationBreachRisk": {
        "type": "string",
        "enum": [
          "OBSERVATION_BREACH_RISK_UNSPECIFIED",
          "OBSERVATION_BREACH_RISK_INFO",
          "OBSERVATION_BREACH_RISK_LOW",
          "OBSERVATION_BREACH_RISK_MEDIUM",
          "OBSERVATION_BREACH_RISK_HIGH",
          "OBSERVATION_BREACH_RISK_CRITICAL"
        ],
        "default": "OBSERVATION_BREACH_RISK_UNSPECIFIED",
        "title": "/ ObservationBreachRisk enumeration"
      },
      "ObservationCategory": {
        "type": "string",
        "enum": [
          "OBSERVATION_CATEGORY_UNSPECIFIED",
          "OBSERVATION_CATEGORY_APPLICATION_SECURITY",
          "OBSERVATION_CATEGORY_NETWORK_SECURITY",
          "OBSERVATION_CATEGORY_DNS_HEALTH",
          "OBSERVATION_CATEGORY_INFORMATION_LEAK",
          "OBSERVATION_CATEGORY_VULNERABILITY"
        ],
        "default": "OBSERVATION_CATEGORY_UNSPECIFIED",
        "title": "/ ObservationCategory enumeration"
      },
      "ObservationDetails": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "longDescription": {
            "type": "string"
          },
          "shortDescription": {
            "type": "string"
          },
          "recommendation": {
            "type": "string"
          }
        },
        "title": "/ ObservationDetails class",
        "required": [
          "title",
          "longDescription",
          "shortDescription",
          "recommendation"
        ]
      },
      "ObservationGroup": {
        "type": "object",
        "properties": {
          "observationGroupOrn": {
            "type": "string",
            "description": "ORN identifying this observation group (format: `orn:<version>:observation:group:<key>:<view-owner-domain>`).\nPass this to GetObservations' observation_group_orn field to list the group's individual observations."
          },
          "name": {
            "type": "string",
            "description": "Customer-facing name for the group (e.g. the vulnerability/observation name)."
          },
          "cve": {
            "$ref": "#/components/schemas/VulnerabilityDetail"
          },
          "severity": {
            "$ref": "#/components/schemas/ObservationSeverity"
          },
          "remediationStatus": {
            "$ref": "#/components/schemas/RemediationStatus"
          },
          "observationCategory": {
            "$ref": "#/components/schemas/ObservationCategory"
          },
          "observationType": {
            "$ref": "#/components/schemas/ObservationType"
          },
          "observationsCount": {
            "type": "integer",
            "format": "int32",
            "description": "Count of observations rolled up into this group."
          }
        },
        "description": "A rollup of observations sharing the same vulnerability/name key (e.g. all findings for a\nsingle CVE), with aggregate counts across the underlying observations.",
        "required": [
          "observationGroupOrn",
          "name",
          "cve",
          "severity",
          "remediationStatus",
          "observationCategory",
          "observationType",
          "observationsCount"
        ]
      },
      "ObservationImpact": {
        "type": "object",
        "properties": {
          "v3": {
            "$ref": "#/components/schemas/ObservationImpactV3"
          }
        },
        "description": "Forward-compatible container for business impact; selects the active encoding (v3 numeric impact today)."
      },
      "ObservationImpactV3": {
        "type": "object",
        "properties": {
          "impact": {
            "type": "integer",
            "format": "int32"
          }
        },
        "description": "Numeric business-impact score used in newer observation payloads (complements threat/breach severity).",
        "required": [
          "impact"
        ]
      },
      "ObservationSeverity": {
        "type": "object",
        "properties": {
          "v3": {
            "$ref": "#/components/schemas/ObservationSeverityV3"
          }
        },
        "description": "Optional wrapper so clients can consume v3 severity without breaking when future versions are added."
      },
      "ObservationSeverityV3": {
        "type": "object",
        "properties": {
          "threatLevel": {
            "$ref": "#/components/schemas/ObservationThreatLevel"
          },
          "breachRisk": {
            "$ref": "#/components/schemas/ObservationBreachRisk"
          }
        },
        "description": "Paired threat level and breach-risk labels that form the v3 severity model for an observation.",
        "required": [
          "threatLevel",
          "breachRisk"
        ]
      },
      "ObservationStatus": {
        "type": "string",
        "enum": [
          "OBSERVATION_STATUS_UNSPECIFIED",
          "OBSERVATION_STATUS_OPEN",
          "OBSERVATION_STATUS_RESOLVED",
          "OBSERVATION_STATUS_IN_PROGRESS",
          "OBSERVATION_STATUS_PENDING_SSC_REVIEW",
          "OBSERVATION_STATUS_REOPENED",
          "OBSERVATION_STATUS_DECAYED",
          "OBSERVATION_STATUS_ASSET_DEATTRIBUTED"
        ],
        "default": "OBSERVATION_STATUS_UNSPECIFIED",
        "description": "High-level workflow state of an observation for UX and reporting (open, resolved, pending review, decayed, etc.).\n\n - OBSERVATION_STATUS_OPEN: Open: Vendor Action = NULL.\n - OBSERVATION_STATUS_RESOLVED: Vendor Action in {Fixed, Compensating Control, Cannot Reproduce, [Blank]} AND SSC accepted.\nOR VRM “My Action” = Risk Accepted\n - OBSERVATION_STATUS_IN_PROGRESS: In Progress: Vendor Action = Investigating.\n - OBSERVATION_STATUS_PENDING_SSC_REVIEW: Pending SSC Review: Vendor Action in {Fixed, Compensating Control, Cannot Reproduce}, awaiting SSC decision.\n - OBSERVATION_STATUS_REOPENED: Reopened: SSC denied the vendor response and Vendor Action becomes empty again (history shows what it was)\n - OBSERVATION_STATUS_DECAYED: SSC no longer observes the issue; decayed reason recorded.\n - OBSERVATION_STATUS_ASSET_DEATTRIBUTED: SSC modified the attribution of the asset to the vendor that removed the observation."
      },
      "ObservationThreatLevel": {
        "type": "string",
        "enum": [
          "OBSERVATION_THREAT_LEVEL_UNSPECIFIED",
          "OBSERVATION_THREAT_LEVEL_INFO",
          "OBSERVATION_THREAT_LEVEL_LOW",
          "OBSERVATION_THREAT_LEVEL_MEDIUM",
          "OBSERVATION_THREAT_LEVEL_HIGH",
          "OBSERVATION_THREAT_LEVEL_CRITICAL"
        ],
        "default": "OBSERVATION_THREAT_LEVEL_UNSPECIFIED",
        "title": "/ ObservationThreatLevel enumeration"
      },
      "ObservationType": {
        "type": "string",
        "enum": [
          "OBSERVATION_TYPE_UNSPECIFIED",
          "OBSERVATION_TYPE_VULNERABILITY",
          "OBSERVATION_TYPE_APPLICATION_MISCONFIGURATION",
          "OBSERVATION_TYPE_DNS_MISCONFIGURATION",
          "OBSERVATION_TYPE_INFORMATION_LEAK",
          "OBSERVATION_TYPE_INSECURE_ENDPOINT",
          "OBSERVATION_TYPE_OUT_OF_DATE_PRODUCTS",
          "OBSERVATION_TYPE_POTENTIAL_COMPROMISE",
          "OBSERVATION_TYPE_TYPOSQUATTING",
          "OBSERVATION_TYPE_BREACH"
        ],
        "default": "OBSERVATION_TYPE_UNSPECIFIED",
        "title": "/ ObservationType enumeration"
      },
      "ObservationsQueryMode": {
        "type": "string",
        "enum": [
          "OBSERVATIONS_QUERY_MODE_UNSPECIFIED",
          "OBSERVATIONS_QUERY_MODE_OPEN",
          "OBSERVATIONS_QUERY_MODE_RESOLVED"
        ],
        "default": "OBSERVATIONS_QUERY_MODE_UNSPECIFIED",
        "description": "Whether list endpoints return open items, resolved items, or an unspecified default."
      },
      "OffboardVendorBody": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "description": "Optional caller-supplied audit reason recorded with the offboarding action."
          }
        },
        "description": "Request to offboard a vendor already in the caller's directory.\nOrganization scope is derived from the access token, not from this message."
      },
      "OffboardVendorResponse": {
        "type": "object",
        "properties": {
          "vendor": {
            "$ref": "#/components/schemas/vendor.v1.Vendor"
          }
        },
        "description": "Response containing the offboarded vendor.",
        "required": [
          "vendor"
        ]
      },
      "PublicAuditLogAction": {
        "type": "string",
        "enum": [
          "PUBLIC_AUDIT_LOG_ACTION_UNSPECIFIED",
          "PUBLIC_AUDIT_LOG_ACTION_CREATE",
          "PUBLIC_AUDIT_LOG_ACTION_UPDATE",
          "PUBLIC_AUDIT_LOG_ACTION_DELETE",
          "PUBLIC_AUDIT_LOG_ACTION_LOGIN",
          "PUBLIC_AUDIT_LOG_ACTION_LOGOUT",
          "PUBLIC_AUDIT_LOG_ACTION_ENABLE",
          "PUBLIC_AUDIT_LOG_ACTION_DISABLE",
          "PUBLIC_AUDIT_LOG_ACTION_EXPORT",
          "PUBLIC_AUDIT_LOG_ACTION_GENERATE",
          "PUBLIC_AUDIT_LOG_ACTION_VIEW",
          "PUBLIC_AUDIT_LOG_ACTION_ADD",
          "PUBLIC_AUDIT_LOG_ACTION_REMOVE",
          "PUBLIC_AUDIT_LOG_ACTION_IMPERSONATE",
          "PUBLIC_AUDIT_LOG_ACTION_RESTORE",
          "PUBLIC_AUDIT_LOG_ACTION_PURGE",
          "PUBLIC_AUDIT_LOG_ACTION_DUPLICATE",
          "PUBLIC_AUDIT_LOG_ACTION_RENAME",
          "PUBLIC_AUDIT_LOG_ACTION_MOVE",
          "PUBLIC_AUDIT_LOG_ACTION_REVOKE",
          "PUBLIC_AUDIT_LOG_ACTION_ARCHIVE",
          "PUBLIC_AUDIT_LOG_ACTION_UNARCHIVE",
          "PUBLIC_AUDIT_LOG_ACTION_SEND",
          "PUBLIC_AUDIT_LOG_ACTION_MARK_READ",
          "PUBLIC_AUDIT_LOG_ACTION_RECEIVE",
          "PUBLIC_AUDIT_LOG_ACTION_DOWNLOAD",
          "PUBLIC_AUDIT_LOG_ACTION_BULK",
          "PUBLIC_AUDIT_LOG_ACTION_BOUNCE",
          "PUBLIC_AUDIT_LOG_ACTION_OPEN",
          "PUBLIC_AUDIT_LOG_ACTION_CLICK",
          "PUBLIC_AUDIT_LOG_ACTION_SPAM",
          "PUBLIC_AUDIT_LOG_ACTION_REJECT",
          "PUBLIC_AUDIT_LOG_ACTION_ACCESS_DENIED"
        ],
        "default": "PUBLIC_AUDIT_LOG_ACTION_UNSPECIFIED",
        "description": "Allow-listed action verbs. An event recorded with an unlisted verb is\nreturned as UNSPECIFIED rather than dropped."
      },
      "PublicAuditLogActor": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          }
        },
        "description": "Principal who performed an audited action."
      },
      "PublicAuditLogEntityType": {
        "type": "string",
        "enum": [
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_UNSPECIFIED",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_USER",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_TEAM",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_LOGIN",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_MFA",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_SCIM",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_ACCESS_TOKEN",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_INVITE",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_ORGANIZATION",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_PORTFOLIO",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_REPORT",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_SCORECARD",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_AUTH_POLICY",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_CUSTOM_FIELD",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_DASHBOARD",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_RULE",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_TEMPLATE",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_USER_SETTING",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_CONVERSATION",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_MESSAGE",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_EMAIL_EVENT",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_INBOUND_EMAIL",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_FILE",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_FOLDER",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_FILE_VERSION",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_VAULT",
          "PUBLIC_AUDIT_LOG_ENTITY_TYPE_SHARE"
        ],
        "default": "PUBLIC_AUDIT_LOG_ENTITY_TYPE_UNSPECIFIED",
        "description": "Allow-listed target resource kinds. An unlisted kind is returned as\nUNSPECIFIED rather than dropped."
      },
      "PublicAuditLogEvent": {
        "type": "object",
        "properties": {
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "service": {
            "$ref": "#/components/schemas/PublicAuditLogProductArea"
          },
          "action": {
            "$ref": "#/components/schemas/PublicAuditLogAction"
          },
          "actor": {
            "$ref": "#/components/schemas/PublicAuditLogActor"
          },
          "organization": {
            "$ref": "#/components/schemas/PublicAuditLogOrganization"
          },
          "target": {
            "$ref": "#/components/schemas/PublicAuditLogTarget"
          },
          "result": {
            "$ref": "#/components/schemas/PublicAuditLogResult"
          }
        },
        "description": "A single audit event: who did what, to what, and whether it succeeded.\nCurated projection of the internal record — raw request bodies, caller IP and\nuser agent, failure diagnostics, HTTP method and route, correlation ids,\nstorage metadata, and internal service names are never returned.",
        "required": [
          "service",
          "action",
          "result"
        ]
      },
      "PublicAuditLogOrganization": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "domain": {
            "type": "string"
          }
        },
        "description": "Organization the audited action belongs to."
      },
      "PublicAuditLogProductArea": {
        "type": "string",
        "enum": [
          "PUBLIC_AUDIT_LOG_PRODUCT_AREA_UNSPECIFIED",
          "PUBLIC_AUDIT_LOG_PRODUCT_AREA_USERS",
          "PUBLIC_AUDIT_LOG_PRODUCT_AREA_PORTFOLIOS",
          "PUBLIC_AUDIT_LOG_PRODUCT_AREA_REPORTS",
          "PUBLIC_AUDIT_LOG_PRODUCT_AREA_SCORECARDS",
          "PUBLIC_AUDIT_LOG_PRODUCT_AREA_REPORTING",
          "PUBLIC_AUDIT_LOG_PRODUCT_AREA_NOTIFICATIONS",
          "PUBLIC_AUDIT_LOG_PRODUCT_AREA_FILE_VAULT",
          "PUBLIC_AUDIT_LOG_PRODUCT_AREA_RULES_MANAGEMENT"
        ],
        "default": "PUBLIC_AUDIT_LOG_PRODUCT_AREA_UNSPECIFIED",
        "description": "Customer-facing product areas whose audit events are readable. Exactly one\nscopes every ListAuditLogs call. Internal service names are never exposed."
      },
      "PublicAuditLogResult": {
        "type": "string",
        "enum": [
          "PUBLIC_AUDIT_LOG_RESULT_UNSPECIFIED",
          "PUBLIC_AUDIT_LOG_RESULT_SUCCESS",
          "PUBLIC_AUDIT_LOG_RESULT_FAILURE"
        ],
        "default": "PUBLIC_AUDIT_LOG_RESULT_UNSPECIFIED",
        "description": "Outcome of an audited action."
      },
      "PublicAuditLogTarget": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/PublicAuditLogEntityType"
          },
          "ids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "display": {
            "type": "string",
            "description": "For display only; wording is not part of the contract."
          }
        },
        "description": "Resource an audited action was performed on. `ids` is repeated so one bulk\naction can name every resource it touched.",
        "required": [
          "type",
          "ids"
        ]
      },
      "PublicAvdFilter": {
        "type": "object",
        "properties": {
          "list": {
            "$ref": "#/components/schemas/PublicAvdFilterList"
          },
          "rule": {
            "$ref": "#/components/schemas/PublicAvdFilterRule"
          }
        },
        "description": "A single node in a public AVD filter tree: either a composite group or an atomic rule."
      },
      "PublicAvdFilterList": {
        "type": "object",
        "properties": {
          "operator": {
            "$ref": "#/components/schemas/FilterOperator"
          },
          "isNegated": {
            "type": "boolean",
            "description": "When true, the combined result of the child filters is negated (logical NOT)."
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicAvdFilter"
            },
            "description": "Child filters combined by the operator."
          }
        },
        "description": "Nested boolean group: AND/OR of child public AVD filters with optional negation.",
        "required": [
          "filters"
        ]
      },
      "PublicAvdFilterOption": {
        "type": "object",
        "properties": {
          "field": {
            "$ref": "#/components/schemas/PublicAvdFilterableFieldRef"
          },
          "comparisons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterComparison"
            },
            "description": "Comparison operators valid for this field."
          },
          "fieldValues": {
            "$ref": "#/components/schemas/DiscreteFilterValues"
          },
          "fieldRange": {
            "$ref": "#/components/schemas/FilterRangeBounds"
          }
        },
        "description": "Describes a public AVD filterable field's allowed comparisons and available discrete values.\nReturned in list responses when include_filter_options is true.",
        "required": [
          "comparisons"
        ]
      },
      "PublicAvdFilterRule": {
        "type": "object",
        "properties": {
          "field": {
            "$ref": "#/components/schemas/PublicAvdFilterableFieldRef"
          },
          "comparison": {
            "$ref": "#/components/schemas/FilterComparison"
          },
          "value": {
            "$ref": "#/components/schemas/FilterValue"
          }
        },
        "description": "Single predicate: which public AVD field, how to compare, and the bound value."
      },
      "PublicAvdFilterableField": {
        "type": "string",
        "enum": [
          "AVD_FIELD_UNSPECIFIED",
          "AVD_FIELD_IS_MONITORED",
          "AVD_FIELD_FOURTH_PARTY",
          "AVD_FIELD_VENDOR",
          "AVD_FIELD_DETECTION_METHOD",
          "AVD_FIELD_FIRST_DETECTED",
          "AVD_FIELD_LAST_DETECTED",
          "AVD_FIELD_PORTFOLIO"
        ],
        "default": "AVD_FIELD_UNSPECIFIED",
        "description": "AVD (Automatic Vendor Detection) fields that external callers may filter on\nvia the public API. The server maps each value to its internal counterpart.\nShared across all public API versions — new fields are added here additively.\n\nAccess control: the public AVD handlers in factor-svc-observations always\nderive `allowed_domains` from the caller's auth metadata and bound every\nquery to it BEFORE any caller-supplied filter is applied, so a filter can\nonly match fourth-party data the caller is already entitled to read. No\nadditional per-value validation of caller-supplied domains is required at\nthe public layer.\n\n - AVD_FIELD_UNSPECIFIED: Default zero value; no filterable field selected (unset sentinel).\n - AVD_FIELD_IS_MONITORED: Whether the fourth-party domain is also directly monitored by the caller's organization.\n - AVD_FIELD_FOURTH_PARTY: Fourth-party display name or registered domain.\n - AVD_FIELD_VENDOR: Portfolio vendor display name or registered domain.\n - AVD_FIELD_DETECTION_METHOD: Connection method by which the vendor -> fourth-party relationship was observed (e.g. HTTP, DNS, LIBRARY).\n - AVD_FIELD_FIRST_DETECTED: Timestamp of the earliest observed connection; supports BETWEEN, GTE, LTE.\n - AVD_FIELD_LAST_DETECTED: Timestamp of the most recent observed connection; supports BETWEEN, GTE, LTE.\n - AVD_FIELD_PORTFOLIO: Portfolio id(s) the connection belongs to; matches if any value matches."
      },
      "PublicAvdFilterableFieldRef": {
        "type": "object",
        "properties": {
          "avdField": {
            "$ref": "#/components/schemas/PublicAvdFilterableField"
          }
        },
        "description": "Wraps the public AVD field reference used as a filter target."
      },
      "PublicFilter": {
        "type": "object",
        "properties": {
          "list": {
            "$ref": "#/components/schemas/PublicFilterList"
          },
          "rule": {
            "$ref": "#/components/schemas/PublicFilterRule"
          }
        },
        "description": "A single node in a public filter tree: either a composite group or an atomic rule."
      },
      "PublicFilterList": {
        "type": "object",
        "properties": {
          "operator": {
            "$ref": "#/components/schemas/FilterOperator"
          },
          "isNegated": {
            "type": "boolean",
            "description": "When true, the combined result of child filters is negated (logical NOT)."
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicFilter"
            },
            "description": "Child filters combined by the operator."
          }
        },
        "description": "Nested boolean group: AND/OR of child public filters with optional negation.",
        "required": [
          "filters"
        ]
      },
      "PublicFilterOption": {
        "type": "object",
        "properties": {
          "field": {
            "$ref": "#/components/schemas/PublicFilterableField"
          },
          "comparisons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterComparison"
            },
            "description": "Comparison operators valid for this field."
          },
          "fieldValues": {
            "$ref": "#/components/schemas/DiscreteFilterValues"
          },
          "fieldRange": {
            "$ref": "#/components/schemas/FilterRangeBounds"
          }
        },
        "description": "Describes a public filterable field's allowed comparisons and available discrete values.\nReturned in GetObservationsResponse when include_filter_options is true.",
        "required": [
          "comparisons"
        ]
      },
      "PublicFilterRule": {
        "type": "object",
        "properties": {
          "field": {
            "$ref": "#/components/schemas/PublicFilterableField"
          },
          "comparison": {
            "$ref": "#/components/schemas/FilterComparison"
          },
          "value": {
            "$ref": "#/components/schemas/FilterValue"
          }
        },
        "description": "Single predicate: which public field, how to compare, and the bound value."
      },
      "PublicFilterableField": {
        "type": "object",
        "properties": {
          "observationsField": {
            "$ref": "#/components/schemas/PublicObservationsFilterableField"
          }
        },
        "description": "Wraps the public observation field reference used as a filter target."
      },
      "PublicFourthPartyGroupItem": {
        "type": "object",
        "properties": {
          "fourthParty": {
            "type": "string",
            "description": "Display name of the fourth party; falls back to the domain when unavailable."
          },
          "isMonitored": {
            "type": "boolean",
            "description": "True when the fourth-party domain is also directly monitored by the caller's organization."
          },
          "connectedVendorCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of portfolio vendors that have at least one connection to this fourth party."
          },
          "vendorTotal": {
            "type": "integer",
            "format": "int32",
            "description": "Total number of vendors in the caller's portfolio (denominator for coverage)."
          },
          "vendorSample": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicFourthPartyVendorSample"
            },
            "description": "A small preview subset of the portfolio vendors connecting to this fourth party."
          },
          "fourthPartyLogoUrl": {
            "type": "string",
            "description": "URL of the fourth-party company logo, sourced from the legal entities service."
          },
          "fourthPartyDomain": {
            "type": "string",
            "description": "Registered domain of the fourth party; use for lookups/linking rather than the display name."
          }
        },
        "description": "One row in the grouped fourth-party view: aggregates all portfolio vendors\nthat connect to a single fourth-party domain.",
        "required": [
          "fourthParty",
          "isMonitored",
          "connectedVendorCount",
          "vendorTotal",
          "vendorSample",
          "fourthPartyLogoUrl"
        ]
      },
      "PublicFourthPartyRelationshipItem": {
        "type": "object",
        "properties": {
          "vendor": {
            "type": "string",
            "description": "Display name of the portfolio vendor originating the connection; falls back to the domain."
          },
          "fourthParty": {
            "type": "string",
            "description": "Display name of the fourth party reached by the vendor; falls back to the domain."
          },
          "isMonitored": {
            "type": "boolean",
            "description": "True when the fourth-party domain is also directly monitored by the caller's organization."
          },
          "connectionMethods": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Stable codes identifying the connection method(s) observed (e.g. \"HTTP\", \"DNS\", \"LIBRARY\")."
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time",
            "description": "Earliest timestamp at which this vendor -> fourth-party connection was observed."
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time",
            "description": "Most recent timestamp at which this connection was observed."
          },
          "vendorLogoUrl": {
            "type": "string",
            "description": "URL of the portfolio vendor's company logo, sourced from the legal entities service."
          },
          "fourthPartyLogoUrl": {
            "type": "string",
            "description": "URL of the fourth-party company logo, sourced from the legal entities service."
          },
          "vendorDomain": {
            "type": "string",
            "description": "Registered domain of the portfolio vendor; use for lookups/linking rather than the display name."
          },
          "fourthPartyDomain": {
            "type": "string",
            "description": "Registered domain of the fourth party; use for lookups/linking rather than the display name."
          }
        },
        "description": "A single connection between a portfolio vendor and a fourth-party domain,\nwith the connection signals and temporal bounds observed for that pair.",
        "required": [
          "vendor",
          "fourthParty",
          "isMonitored",
          "connectionMethods",
          "firstSeen",
          "lastSeen",
          "vendorLogoUrl",
          "fourthPartyLogoUrl"
        ]
      },
      "PublicFourthPartyVendorItem": {
        "type": "object",
        "properties": {
          "vendorDomain": {
            "type": "string",
            "description": "Registered domain of the portfolio vendor."
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time",
            "description": "Most recent timestamp at which any connection from this vendor to the requested fourth party was observed."
          },
          "vendorName": {
            "type": "string",
            "description": "Display name of the portfolio vendor; falls back to vendor_domain when unavailable."
          },
          "connectionCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of connections from this vendor to the requested fourth party, across all connection methods."
          }
        },
        "description": "One portfolio vendor that connects to a specific fourth party, with the\nrecency of its latest observed connection.",
        "required": [
          "vendorDomain",
          "lastSeen",
          "vendorName",
          "connectionCount"
        ]
      },
      "PublicFourthPartyVendorSample": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Display name of the vendor; falls back to the domain when unavailable."
          },
          "domain": {
            "type": "string",
            "description": "Registered domain of the vendor (e.g. \"acme.com\")."
          },
          "logoUrl": {
            "type": "string",
            "description": "URL of the vendor's company logo, sourced from the legal entities service."
          }
        },
        "description": "A lightweight preview of a portfolio vendor that connects to a fourth party.",
        "required": [
          "name",
          "domain",
          "logoUrl"
        ]
      },
      "PublicLetterGrade": {
        "type": "string",
        "enum": [
          "PUBLIC_LETTER_GRADE_UNSPECIFIED",
          "PUBLIC_LETTER_GRADE_A",
          "PUBLIC_LETTER_GRADE_B",
          "PUBLIC_LETTER_GRADE_C",
          "PUBLIC_LETTER_GRADE_D",
          "PUBLIC_LETTER_GRADE_F"
        ],
        "default": "PUBLIC_LETTER_GRADE_UNSPECIFIED",
        "description": "Letter grade classification for a curated public score, mirroring the internal LetterGrade\nenum under a fully-prefixed public name (public enums in this service are never bare tokens)."
      },
      "PublicObservationsFilterableField": {
        "type": "string",
        "enum": [
          "OBSERVATIONS_FIELD_UNSPECIFIED",
          "OBSERVATIONS_FIELD_SEVERITY",
          "OBSERVATIONS_FIELD_OBSERVATION_TYPE",
          "OBSERVATIONS_FIELD_OBSERVATION_NAME",
          "OBSERVATIONS_FIELD_OBSERVATION_STATUS",
          "OBSERVATIONS_FIELD_ASSET_NAME",
          "OBSERVATIONS_FIELD_ASSET_TYPE",
          "OBSERVATIONS_FIELD_ASSET_KEY",
          "OBSERVATIONS_FIELD_PORT_NUMBER",
          "OBSERVATIONS_FIELD_CVSS_SCORE",
          "OBSERVATIONS_FIELD_EPSS_SCORE",
          "OBSERVATIONS_FIELD_IS_IN_CISA_KEV",
          "OBSERVATIONS_FIELD_FIRST_SEEN",
          "OBSERVATIONS_FIELD_LAST_SEEN",
          "OBSERVATIONS_FIELD_FLAGGED",
          "OBSERVATIONS_FIELD_APPROVAL_STATUS",
          "OBSERVATIONS_FIELD_EXCLUDED_REASON_TYPE",
          "OBSERVATIONS_FIELD_RESOLVED_AT",
          "OBSERVATIONS_FIELD_VENDOR",
          "OBSERVATIONS_FIELD_REMEDIATION_STATUS",
          "OBSERVATIONS_FIELD_PORTFOLIO",
          "OBSERVATIONS_FIELD_OBSERVATION_NAME_KEY",
          "OBSERVATIONS_FIELD_PORTFOLIO_NAME"
        ],
        "default": "OBSERVATIONS_FIELD_UNSPECIFIED",
        "description": "Observation fields that external callers may filter on via the public API.\nThe server maps each value to its internal counterpart. Shared across all public API versions —\nnew fields are added here additively.\n\nAccess control for tenant-scoped fields (VENDOR, PORTFOLIO):\n  These fields name tenant/organization-scoped concepts and were previously excluded from the\n  public surface. They are safe to expose here because the public GetObservations handler in\n  factor-svc-observations always derives `allowed_domains` from the caller's auth metadata\n  (PublicObservationController throws UNAUTHENTICATED if it is missing) and forwards it into\n  every observation query. ClickHouse rows are bounded to `allowed_domains` BEFORE any\n  caller-supplied filter is applied, so a VENDOR or PORTFOLIO filter can only match\n  observations the caller is already entitled to read. A caller filtering by a portfolio or\n  vendor they do not own receives an empty result rather than cross-tenant data — there is\n  no enumeration oracle because the empty result is indistinguishable from \"no findings\".\n  No additional validation of caller-supplied portfolio ids / vendor domains is required at\n  the public layer; do NOT add such a check in this schema or in the public mapper.\n\nInternal fields intentionally excluded from this surface:\n  - OBSERVATION_GROUP_KEY is an internal grouping key (use OBSERVATION_NAME or OBSERVATION_NAME_KEY).\n  - VIEW_OWNER_DOMAIN is set server-side from auth metadata, not a caller-supplied filter.\n  - REQUESTORS exposes per-user remediation requester identity; gated until a privacy review.\n  - HAS_REMEDIATION_REQUEST is not yet wired in getPublicFilterOptions; gated until then.\n\n - OBSERVATIONS_FIELD_SEVERITY: Threat severity level (e.g. LOW, MEDIUM, HIGH, CRITICAL).\n - OBSERVATIONS_FIELD_OBSERVATION_TYPE: Observation type.\n - OBSERVATIONS_FIELD_OBSERVATION_NAME: Human-readable observation name; supports CONTAINS for substring search.\n - OBSERVATIONS_FIELD_OBSERVATION_STATUS: Lifecycle status (e.g. OPEN, RESOLVED, IN_PROGRESS).\n - OBSERVATIONS_FIELD_ASSET_NAME: IP address, URL, or domain name of the affected asset.\n - OBSERVATIONS_FIELD_ASSET_TYPE: Asset category (IP_PORT, URL, DNS, CREDENTIALS).\n - OBSERVATIONS_FIELD_ASSET_KEY: Composite asset identifier combining type and address.\n - OBSERVATIONS_FIELD_PORT_NUMBER: TCP/UDP port number associated with the asset.\n - OBSERVATIONS_FIELD_CVSS_SCORE: CVSS numeric score (0–10); supports BETWEEN, GTE, LTE.\n - OBSERVATIONS_FIELD_EPSS_SCORE: EPSS exploit-prediction score (0–1); supports BETWEEN, GTE, LTE.\n - OBSERVATIONS_FIELD_IS_IN_CISA_KEV: Whether the observation is listed in CISA's Known Exploited Vulnerabilities catalog.\n - OBSERVATIONS_FIELD_FIRST_SEEN: Timestamp of the earliest detection; supports BETWEEN, GTE, LTE.\n - OBSERVATIONS_FIELD_LAST_SEEN: Timestamp of the most recent detection; supports BETWEEN, GTE, LTE.\n - OBSERVATIONS_FIELD_FLAGGED: Whether the observation has been flagged for review.\n - OBSERVATIONS_FIELD_APPROVAL_STATUS: Approval status.\n - OBSERVATIONS_FIELD_EXCLUDED_REASON_TYPE: Reason category when an observation is excluded (ACCEPTED_RISK, FALSE_POSITIVE, LOW_RISK, OTHER).\n - OBSERVATIONS_FIELD_RESOLVED_AT: Timestamp when the observation was resolved; supports BETWEEN, GTE, LTE.\n - OBSERVATIONS_FIELD_VENDOR: Vendor (third-party organization) domain associated with the observation.\n - OBSERVATIONS_FIELD_REMEDIATION_STATUS: Current remediation workflow status (e.g. NOT_STARTED, IN_PROGRESS, COMPLETED).\n - OBSERVATIONS_FIELD_PORTFOLIO: Portfolio id(s) the observation belongs to; matches if any value matches.\n - OBSERVATIONS_FIELD_OBSERVATION_NAME_KEY: Stable key for the observation name (de-duped, internal identifier).\n - OBSERVATIONS_FIELD_PORTFOLIO_NAME: Portfolio name(s) the observation belongs to; matches if any portfolio the observation\nbelongs to has a matching name. The server resolves names to ids within the caller's\nallowed domains before executing the query. Name matching is case-insensitive exact.\nUnknown names return NOT_FOUND; names matching multiple portfolios return\nINVALID_ARGUMENT; empty or whitespace-only names return INVALID_ARGUMENT."
      },
      "PublicRiskLevel": {
        "type": "string",
        "enum": [
          "PUBLIC_RISK_LEVEL_UNSPECIFIED",
          "PUBLIC_RISK_LEVEL_VERY_LOW",
          "PUBLIC_RISK_LEVEL_LOW",
          "PUBLIC_RISK_LEVEL_MODERATE",
          "PUBLIC_RISK_LEVEL_HIGH",
          "PUBLIC_RISK_LEVEL_VERY_HIGH",
          "PUBLIC_RISK_LEVEL_NOT_APPLICABLE"
        ],
        "default": "PUBLIC_RISK_LEVEL_UNSPECIFIED",
        "description": "Risk level classification for a curated public score, mirroring the internal RiskLevel enum."
      },
      "PublicSecurityEventFilter": {
        "type": "object",
        "properties": {
          "list": {
            "$ref": "#/components/schemas/PublicSecurityEventFilterList"
          },
          "rule": {
            "$ref": "#/components/schemas/PublicSecurityEventFilterRule"
          }
        },
        "description": "A single node in a public security-event filter tree: either a composite group\nor an atomic rule."
      },
      "PublicSecurityEventFilterList": {
        "type": "object",
        "properties": {
          "operator": {
            "$ref": "#/components/schemas/FilterOperator"
          },
          "isNegated": {
            "type": "boolean",
            "description": "When true, the combined result of child filters is negated (logical NOT)."
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicSecurityEventFilter"
            },
            "description": "Child filters combined by the operator."
          }
        },
        "description": "Nested boolean group: AND/OR of child public filters with optional negation.",
        "required": [
          "filters"
        ]
      },
      "PublicSecurityEventFilterRule": {
        "type": "object",
        "properties": {
          "field": {
            "$ref": "#/components/schemas/PublicSecurityEventFilterableField"
          },
          "comparison": {
            "$ref": "#/components/schemas/FilterComparison"
          },
          "value": {
            "$ref": "#/components/schemas/FilterValue"
          }
        },
        "description": "Single predicate: which public field, how to compare, and the bound value."
      },
      "PublicSecurityEventFilterableField": {
        "type": "object",
        "properties": {
          "securityEventField": {
            "$ref": "#/components/schemas/PublicSecurityEventsFilterableField"
          }
        },
        "description": "Wraps the public security-event field reference used as a filter target."
      },
      "PublicSecurityEventsFilterableField": {
        "type": "string",
        "enum": [
          "SECURITY_EVENTS_FIELD_UNSPECIFIED",
          "SECURITY_EVENTS_FIELD_FIRST_DETECTED",
          "SECURITY_EVENTS_FIELD_LAST_UPDATED",
          "SECURITY_EVENTS_FIELD_TITLE",
          "SECURITY_EVENTS_FIELD_NATURE",
          "SECURITY_EVENTS_FIELD_SUBTYPE",
          "SECURITY_EVENTS_FIELD_STATUS",
          "SECURITY_EVENTS_FIELD_SEVERITY",
          "SECURITY_EVENTS_FIELD_IMPACT_REASONING",
          "SECURITY_EVENTS_FIELD_VENDOR"
        ],
        "default": "SECURITY_EVENTS_FIELD_UNSPECIFIED",
        "description": "Security-event fields external callers may filter on for GetSecurityEventsFeed\nand GetImpactedCompanies. The server maps each value to its internal\ncounterpart. Curated, additive-only subset of the internal\nfactor_protos.utility.filters.v1.BreachesFilterableField.\n\nAccess control: as with the public Observations filter surface, these fields\n(including VENDOR) are safe to expose because every handler for this service\nderives the caller's allowed organization/vendor scope from auth metadata and\napplies it BEFORE any caller-supplied filter — a caller can only ever narrow\nresults they were already entitled to read.\n\n - SECURITY_EVENTS_FIELD_FIRST_DETECTED: First detection time on the event cluster; supports BETWEEN, GTE, LTE.\n - SECURITY_EVENTS_FIELD_LAST_UPDATED: Last update time on the event cluster; supports BETWEEN, GTE, LTE.\n - SECURITY_EVENTS_FIELD_TITLE: Headline text; supports CONTAINS for substring search.\n - SECURITY_EVENTS_FIELD_NATURE: Broad classification (compromise vs threat).\n - SECURITY_EVENTS_FIELD_SUBTYPE: Fine-grained classification within nature.\n - SECURITY_EVENTS_FIELD_STATUS: Caller-organization (VRM) lifecycle status.\n - SECURITY_EVENTS_FIELD_SEVERITY: Severity rank derived from nature.\n - SECURITY_EVENTS_FIELD_IMPACT_REASONING: How an impacted company is tied to the event (GetImpactedCompanies tab filter).\n - SECURITY_EVENTS_FIELD_VENDOR: Vendor (impacted company) domain associated with the event."
      },
      "PublicVendorFilter": {
        "type": "object",
        "properties": {
          "list": {
            "$ref": "#/components/schemas/PublicVendorFilterList"
          },
          "rule": {
            "$ref": "#/components/schemas/PublicVendorFilterRule"
          }
        },
        "description": "A single node in a public vendor filter tree: either a composite group or an atomic rule."
      },
      "PublicVendorFilterList": {
        "type": "object",
        "properties": {
          "operator": {
            "$ref": "#/components/schemas/FilterOperator"
          },
          "isNegated": {
            "type": "boolean",
            "description": "When true, the combined result of the child filters is negated (logical NOT)."
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicVendorFilter"
            },
            "description": "Child filters combined by the operator."
          }
        },
        "description": "Nested boolean group: AND/OR of child public vendor filters with optional negation.",
        "required": [
          "filters"
        ]
      },
      "PublicVendorFilterOption": {
        "type": "object",
        "properties": {
          "field": {
            "$ref": "#/components/schemas/PublicVendorFilterableFieldRef"
          },
          "comparisons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterComparison"
            },
            "description": "Comparison operators valid for this field."
          },
          "fieldValues": {
            "$ref": "#/components/schemas/DiscreteFilterValues"
          },
          "fieldRange": {
            "$ref": "#/components/schemas/FilterRangeBounds"
          }
        },
        "description": "Describes a public vendor filterable field's allowed comparisons and available discrete values.\nReturned in ListVendorsResponse when include_filter_options is true.",
        "required": [
          "comparisons"
        ]
      },
      "PublicVendorFilterRule": {
        "type": "object",
        "properties": {
          "field": {
            "$ref": "#/components/schemas/PublicVendorFilterableFieldRef"
          },
          "comparison": {
            "$ref": "#/components/schemas/FilterComparison"
          },
          "value": {
            "$ref": "#/components/schemas/FilterValue"
          }
        },
        "description": "Single predicate: which public vendor field, how to compare, and the bound value."
      },
      "PublicVendorFilterableFieldRef": {
        "type": "object",
        "properties": {
          "vendorsField": {
            "$ref": "#/components/schemas/PublicVendorsFilterableField"
          }
        },
        "description": "Wraps the public vendor field reference used as a filter target."
      },
      "PublicVendorScore": {
        "type": "object",
        "properties": {
          "score": {
            "type": "integer",
            "format": "int32",
            "description": "The rounded integer score (0-100)."
          },
          "grade": {
            "$ref": "#/components/schemas/PublicLetterGrade"
          },
          "riskLevel": {
            "$ref": "#/components/schemas/PublicRiskLevel"
          }
        },
        "description": "A single curated score value: a 0-100 rounded score, its letter grade, and risk level."
      },
      "PublicVendorsFilterableField": {
        "type": "string",
        "enum": [
          "VENDORS_FIELD_UNSPECIFIED",
          "VENDORS_FIELD_DOMAIN_NAME",
          "VENDORS_FIELD_COMPANY_NAME",
          "VENDORS_FIELD_COMPANY_INDUSTRY_CATEGORY",
          "VENDORS_FIELD_LIFECYCLE_STATUS",
          "VENDORS_FIELD_IS_MONITORED",
          "VENDORS_FIELD_DATA_REGION",
          "VENDORS_FIELD_RISK_LEVEL",
          "VENDORS_FIELD_BUSINESS_IMPACT",
          "VENDORS_FIELD_DATA_TYPES_SHARED",
          "VENDORS_FIELD_ACCESS_TYPES",
          "VENDORS_FIELD_VENDOR_ID",
          "VENDORS_FIELD_CONTRACT_VALUE",
          "VENDORS_FIELD_CONTRACT_END_DATE",
          "VENDORS_FIELD_LAST_ASSESSED_DATE",
          "VENDORS_FIELD_CREATED_AT",
          "VENDORS_FIELD_UPDATED_AT"
        ],
        "default": "VENDORS_FIELD_UNSPECIFIED",
        "description": "Vendor-directory fields that external callers may filter on via the public API.\nThe server maps each value to its internal counterpart and rejects any field not\nlisted here with INVALID_ARGUMENT. Shared across all public API versions — new\nfields are added here additively.\n\nAccess control: the public ListVendors handler always derives the caller's\norganization scope from the access token and bounds every query to the caller's\nown vendor directory BEFORE any caller-supplied filter is applied, so a filter can\nonly ever narrow results the caller is already entitled to read. No per-value\ntenant validation of caller-supplied filter values is required at the public layer.\n\nFields intentionally excluded from this filterable surface:\n  - id is a per-vendor lookup key (use GetVendor), not a directory filter.\n  - company_logo_url is a display-only asset URL with no meaningful filter semantics.\n\n - VENDORS_FIELD_UNSPECIFIED: Default zero value; no filterable field selected (unset sentinel).\n - VENDORS_FIELD_DOMAIN_NAME: Primary domain name of the vendor; supports EQ and CONTAINS (substring search).\n - VENDORS_FIELD_COMPANY_NAME: Display name of the vendor company; supports EQ and CONTAINS (substring search).\n - VENDORS_FIELD_COMPANY_INDUSTRY_CATEGORY: Industry category of the vendor company; supports EQ. Match one value with a\nscalar value, or any-of a set with a string_list_value (IN-style).\n - VENDORS_FIELD_LIFECYCLE_STATUS: Lifecycle status of the vendor (VendorLifecycleStatus token); supports EQ. Match\none value with a scalar value, or any-of a set with a string_list_value.\n - VENDORS_FIELD_IS_MONITORED: Whether the vendor is actively monitored; supports EQ.\n - VENDORS_FIELD_DATA_REGION: Data region where the vendor operates (DataRegion token); supports EQ. Match one\nvalue with a scalar value, or any-of a set with a string_list_value.\n - VENDORS_FIELD_RISK_LEVEL: Risk level assigned to the vendor (RiskLevel token); supports EQ. Match one value\nwith a scalar value, or any-of a set with a string_list_value.\n - VENDORS_FIELD_BUSINESS_IMPACT: Business impact if the vendor is compromised (BusinessImpact token); supports EQ.\nMatch one value with a scalar value, or any-of a set with a string_list_value.\n - VENDORS_FIELD_DATA_TYPES_SHARED: Categories of data shared with the vendor (DataTypeShared tokens); supports EQ with\na string_list_value for an any-of match.\n - VENDORS_FIELD_ACCESS_TYPES: Types of access granted to the vendor (AccessType tokens); supports EQ with a\nstring_list_value for an any-of match.\n - VENDORS_FIELD_VENDOR_ID: Customer-defined free-text identifier for the vendor; supports EQ and CONTAINS.\n - VENDORS_FIELD_CONTRACT_VALUE: Monetary value of the contract in minor currency units; supports BETWEEN, GTE, LTE.\n - VENDORS_FIELD_CONTRACT_END_DATE: Date the vendor contract expires; supports BETWEEN, GTE, LTE.\n - VENDORS_FIELD_LAST_ASSESSED_DATE: Date the vendor was last assessed/reviewed; supports BETWEEN, GTE, LTE.\n - VENDORS_FIELD_CREATED_AT: Timestamp the vendor was created; supports BETWEEN, GTE, LTE.\n - VENDORS_FIELD_UPDATED_AT: Timestamp the vendor was last updated; supports BETWEEN, GTE, LTE."
      },
      "Questionnaire": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier of the questionnaire."
          },
          "templateId": {
            "type": "string",
            "description": "Id of the template this questionnaire was created from."
          },
          "sent": {
            "type": "boolean",
            "description": "Whether the questionnaire has been sent to the vendor yet."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the questionnaire was created."
          }
        },
        "description": "A questionnaire sent (or staged to be sent) to a vendor, curated for public\nconsumption. Excludes internal ids beyond the public id, audit actors,\nreviewer/suggestion provenance, and respondent PII beyond what the caller's\nown organization already provided when creating it. The submitted\nquestion/answer schema and attached files are not part of this message —\nthey're planned for a dedicated future endpoint, once curated, matching\nthe precedent set for the full template schema in questionnaire_template.proto.",
        "required": [
          "id",
          "templateId",
          "sent",
          "createdAt"
        ]
      },
      "QuestionnaireTemplate": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier of the template."
          },
          "name": {
            "type": "string",
            "description": "Display name of the template."
          },
          "global": {
            "type": "boolean",
            "description": "Whether this is an SSC-global template available to every organization,\nas opposed to one authored by the caller's own organization."
          }
        },
        "description": "A questionnaire template available to the caller's organization, curated\nfor public consumption. Excludes internal ids beyond the public id, the\nfull question/answer schema body (fetched separately, once curated, by an\nendpoint story), audit actors, and any internal risk-matrix linkage.",
        "required": [
          "id",
          "name",
          "global"
        ]
      },
      "RemediationStatus": {
        "type": "string",
        "enum": [
          "REMEDIATION_STATUS_UNSPECIFIED",
          "REMEDIATION_STATUS_OPEN",
          "REMEDIATION_STATUS_INVESTIGATING",
          "REMEDIATION_STATUS_WONT_FIX",
          "REMEDIATION_STATUS_COMPENSATING_CONTROL",
          "REMEDIATION_STATUS_COMPENSATING_CONTROL_PENDING",
          "REMEDIATION_STATUS_CANNOT_REPRODUCE",
          "REMEDIATION_STATUS_CANNOT_REPRODUCE_PENDING",
          "REMEDIATION_STATUS_RESOLVED",
          "REMEDIATION_STATUS_RESOLVED_PENDING",
          "REMEDIATION_STATUS_REOPENED"
        ],
        "default": "REMEDIATION_STATUS_UNSPECIFIED",
        "description": "- REMEDIATION_STATUS_OPEN: Vendor needs to take action to remediate observation\n - REMEDIATION_STATUS_INVESTIGATING: Vendor is investigating\n - REMEDIATION_STATUS_WONT_FIX: Vendor has decided to not fix the observation. Requires Vrm approval\n - REMEDIATION_STATUS_COMPENSATING_CONTROL: Vendor has uploaded evidence for compensating control. Requires SSC Support approval\n - REMEDIATION_STATUS_CANNOT_REPRODUCE: Vendor cannot reproduce the observation. Requires SSC Support approval\n - REMEDIATION_STATUS_RESOLVED: Vendor has fixed the observation. Requires approval from SSC Support or SSC automated scanning system\n - REMEDIATION_STATUS_REOPENED: SSC or Vrm has rejected Vendor resolution. Vendor is requested to remediate the observation",
        "title": "/ RemediationStatus enumeration"
      },
      "RemoveVendorFromGroupBody": {
        "type": "object",
        "properties": {
          "vendorIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Vendor ids to remove. Required, non-empty, capped at 500 per call. A vendor\nthat isn't currently a member is a no-op, not an error."
          }
        },
        "description": "Vendor ids to remove from a vendor group's membership. Organization scope is\nderived from the access token — this message carries no organization field.",
        "required": [
          "vendorIds"
        ]
      },
      "RemoveVendorFromGroupResponse": {
        "type": "object",
        "properties": {
          "vendorGroup": {
            "$ref": "#/components/schemas/VendorGroup"
          }
        },
        "description": "The vendor group after RemoveVendorFromGroup applies.",
        "required": [
          "vendorGroup"
        ]
      },
      "RequestSecurityEventResponseRequest": {
        "type": "object",
        "properties": {
          "orgDomain": {
            "type": "string",
            "description": "Domain of the organization the security event belongs to."
          },
          "eventId": {
            "type": "string",
            "description": "Unique identifier of the security event."
          },
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompanyContact"
            },
            "description": "Recipients for the remediation-request email batch; must be non-empty after validation."
          },
          "customMessage": {
            "type": "string",
            "description": "Optional body text merged into the remediation-request email template."
          }
        },
        "description": "Input for sending remediation-request emails for a security event.",
        "required": [
          "orgDomain",
          "eventId",
          "contacts"
        ]
      },
      "RequestSecurityEventResponseResponse": {
        "type": "object",
        "properties": {
          "requestsCount": {
            "type": "integer",
            "format": "int32",
            "description": "Count of remediation-request emails accepted for delivery in this call."
          },
          "processedEmails": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Recipient email addresses accepted and queued or sent successfully."
          },
          "notProcessedEmailsInCooldownPeriod": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Recipient email addresses not sent because a request was already sent to them for\nthis security event within the cooldown period."
          },
          "invalidContactEmails": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Recipient email addresses not sent because they are not a valid contact for their company."
          }
        },
        "description": "Outcome of a remediation-request email send.",
        "required": [
          "requestsCount",
          "processedEmails",
          "notProcessedEmailsInCooldownPeriod",
          "invalidContactEmails"
        ]
      },
      "Requestor": {
        "type": "object",
        "properties": {
          "organization": {
            "$ref": "#/components/schemas/observation.v1.Organization"
          }
        },
        "title": "/ Requestor is a Vrm who requests a Vendor to remediate an observation asset",
        "required": [
          "organization"
        ]
      },
      "RiskLevel": {
        "type": "string",
        "enum": [
          "RISK_LEVEL_UNSPECIFIED",
          "RISK_LEVEL_NONE",
          "RISK_LEVEL_LOW",
          "RISK_LEVEL_MEDIUM",
          "RISK_LEVEL_HIGH",
          "RISK_LEVEL_CRITICAL"
        ],
        "default": "RISK_LEVEL_UNSPECIFIED",
        "description": "Risk level assigned to a vendor, as exposed on the public API. Curated public\ncopy of the internal factor_protos.vendor_relationship.v1.RiskLevel. Ordinals\nare kept IDENTICAL to the internal enum for the same cross-boundary-safety\nreason as VendorLifecycleStatus above.\n\n - RISK_LEVEL_UNSPECIFIED: Default zero value; risk level was not set.\n - RISK_LEVEL_NONE: No assessed risk to the vendor relationship.\n - RISK_LEVEL_LOW: Minor or well-mitigated exposure.\n - RISK_LEVEL_MEDIUM: Moderate exposure that warrants periodic monitoring.\n - RISK_LEVEL_HIGH: Significant exposure requiring active oversight.\n - RISK_LEVEL_CRITICAL: Severe exposure requiring immediate remediation."
      },
      "SecurityEvent": {
        "type": "object",
        "properties": {
          "eventId": {
            "type": "string",
            "description": "Opaque identifier grouping related source items into a single event."
          },
          "title": {
            "type": "string",
            "description": "Human-readable headline for the event cluster."
          },
          "summary": {
            "type": "string",
            "description": "Multi-sentence description of the event."
          },
          "nature": {
            "$ref": "#/components/schemas/SecurityEventNature"
          },
          "subtype": {
            "$ref": "#/components/schemas/SecurityEventSubtype"
          },
          "victimOrganization": {
            "type": "string",
            "description": "Primary victim of the security event."
          },
          "affectedOrganizations": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Dedup union of source items' affected parties — companies named in source articles."
          },
          "threatActors": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Dedup union of source items' threat actors."
          },
          "infoLeaked": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Dedup union of source items' leaked information categories."
          },
          "recordsLost": {
            "type": "string",
            "format": "int64",
            "description": "Maximum records lost across the cluster; absent when not estimated."
          },
          "timeline": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SecurityEventTimelineEntry"
            },
            "description": "Ordered timeline rail (one EVENT entry plus one SOURCE entry per source item)."
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SecurityEventSourceItem"
            },
            "description": "Source citations backing the event."
          },
          "severity": {
            "$ref": "#/components/schemas/SecurityEventSeverity"
          },
          "eventDate": {
            "type": "string",
            "format": "date-time",
            "description": "Primary event date (e.g. reported breach date); absent when not available."
          },
          "publishedDate": {
            "type": "string",
            "format": "date-time",
            "description": "When the first source was published; absent when not available."
          },
          "status": {
            "$ref": "#/components/schemas/SecurityEventVrmStatus"
          }
        },
        "description": "Detailed view of one security event, keyed by (org_domain, event_id).",
        "required": [
          "eventId",
          "title",
          "summary",
          "nature",
          "subtype",
          "affectedOrganizations",
          "threatActors",
          "infoLeaked",
          "timeline",
          "sources"
        ]
      },
      "SecurityEventActivityEntry": {
        "type": "object",
        "properties": {
          "activityType": {
            "$ref": "#/components/schemas/SecurityEventActivityType"
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time",
            "description": "When this entry occurred."
          },
          "actorEmail": {
            "type": "string",
            "description": "Email of the user who performed the action; absent for system-driven or\nsynthetic (first-seen) entries."
          },
          "actorOrganization": {
            "$ref": "#/components/schemas/security_event.v1.Organization"
          },
          "message": {
            "type": "string",
            "description": "Free-form message or comment supplied with the action, when applicable."
          }
        },
        "description": "One entry in a vendor's security-event communication log (VRM/vendor/system\nworkflow transitions plus the synthetic first-seen marker). See\nSecurityEventActivityType for why Exchange Hub vendor replies never appear here.",
        "required": [
          "activityType",
          "occurredAt"
        ]
      },
      "SecurityEventActivityType": {
        "type": "string",
        "enum": [
          "SECURITY_EVENT_ACTIVITY_TYPE_UNSPECIFIED",
          "SECURITY_EVENT_ACTIVITY_TYPE_FIRST_SEEN",
          "SECURITY_EVENT_ACTIVITY_TYPE_FLAG",
          "SECURITY_EVENT_ACTIVITY_TYPE_UNFLAG",
          "SECURITY_EVENT_ACTIVITY_TYPE_CLOSE",
          "SECURITY_EVENT_ACTIVITY_TYPE_REOPEN",
          "SECURITY_EVENT_ACTIVITY_TYPE_INITIAL_REQUEST_RESPONSE",
          "SECURITY_EVENT_ACTIVITY_TYPE_FOLLOW_UP_REQUEST_RESPONSE",
          "SECURITY_EVENT_ACTIVITY_TYPE_VENDOR_RESPONSE"
        ],
        "default": "SECURITY_EVENT_ACTIVITY_TYPE_UNSPECIFIED",
        "description": "Classifies a communication-log entry on a vendor's security event detail.\n\nExchange Hub vendor replies (internal `SecurityEventExchangeHubReply`, which is\nCONFIDENTIAL-classified — subject line, conversation id, message id, and raw MIME\nbody fragments) are intentionally NOT represented here or anywhere in this public\ncontract. Only VRM/vendor/system workflow transitions and the synthetic\nfirst-seen marker are surfaced; free-text reply content never crosses the public\nboundary.\n\n - SECURITY_EVENT_ACTIVITY_TYPE_FIRST_SEEN: Synthetic marker: earliest observation seen for this vendor on the event.\n - SECURITY_EVENT_ACTIVITY_TYPE_FLAG: VRM flagged the event for follow-up.\n - SECURITY_EVENT_ACTIVITY_TYPE_UNFLAG: VRM cleared a previously set flag.\n - SECURITY_EVENT_ACTIVITY_TYPE_CLOSE: VRM closed the event.\n - SECURITY_EVENT_ACTIVITY_TYPE_REOPEN: VRM reopened a previously closed event.\n - SECURITY_EVENT_ACTIVITY_TYPE_INITIAL_REQUEST_RESPONSE: VRM sent the initial response request to the vendor.\n - SECURITY_EVENT_ACTIVITY_TYPE_FOLLOW_UP_REQUEST_RESPONSE: VRM sent a follow-up response request to the vendor.\n - SECURITY_EVENT_ACTIVITY_TYPE_VENDOR_RESPONSE: Vendor submitted a triage response to the VRM organization(s)."
      },
      "SecurityEventImpactReasoning": {
        "type": "string",
        "enum": [
          "SECURITY_EVENT_IMPACT_REASONING_UNSPECIFIED",
          "SECURITY_EVENT_IMPACT_REASONING_VICTIM_ENTITY",
          "SECURITY_EVENT_IMPACT_REASONING_NAMED_VICTIM",
          "SECURITY_EVENT_IMPACT_REASONING_CONNECTION_DETECTED"
        ],
        "default": "SECURITY_EVENT_IMPACT_REASONING_UNSPECIFIED",
        "description": "How an impacted company is tied to a security event.\n\n - SECURITY_EVENT_IMPACT_REASONING_VICTIM_ENTITY: The company is the primary victim named on the event.\n - SECURITY_EVENT_IMPACT_REASONING_NAMED_VICTIM: The company is a named victim on the event.\n - SECURITY_EVENT_IMPACT_REASONING_CONNECTION_DETECTED: A connection was detected between the company and the event's primary victim."
      },
      "SecurityEventImpactStatus": {
        "type": "string",
        "enum": [
          "SECURITY_EVENT_IMPACT_STATUS_UNSPECIFIED",
          "SECURITY_EVENT_IMPACT_STATUS_IMPACTED",
          "SECURITY_EVENT_IMPACT_STATUS_NOT_IMPACTED"
        ],
        "default": "SECURITY_EVENT_IMPACT_STATUS_UNSPECIFIED",
        "description": "Assessed impact state for an impacted company on a security event."
      },
      "SecurityEventImpactedCompany": {
        "type": "object",
        "properties": {
          "organization": {
            "$ref": "#/components/schemas/security_event.v1.Organization"
          },
          "impactReasoning": {
            "$ref": "#/components/schemas/SecurityEventImpactReasoning"
          },
          "impactStatus": {
            "$ref": "#/components/schemas/SecurityEventImpactStatus"
          },
          "isFlagged": {
            "type": "boolean",
            "description": "True when this company has been flagged for follow-up on this event."
          },
          "lastActivityDate": {
            "type": "string",
            "format": "date-time",
            "description": "Most recent activity on this company for the event; absent when no activity\nhas been recorded yet."
          }
        },
        "description": "One impacted company row in a security event's vendor overview\n(GetImpactedCompanies) or vendor detail (GetVendorSecurityEventDetail).",
        "required": [
          "organization",
          "impactReasoning",
          "impactStatus"
        ]
      },
      "SecurityEventNature": {
        "type": "string",
        "enum": [
          "SECURITY_EVENT_NATURE_UNSPECIFIED",
          "SECURITY_EVENT_NATURE_COMPROMISE",
          "SECURITY_EVENT_NATURE_THREAT"
        ],
        "default": "SECURITY_EVENT_NATURE_UNSPECIFIED",
        "description": "Broad classification of a security event: a confirmed compromise vs an unverified threat signal.\nCurated copy of factor_protos.io.factor.observation.v1.SecurityEventNature."
      },
      "SecurityEventSeverity": {
        "type": "string",
        "enum": [
          "SECURITY_EVENT_SEVERITY_UNSPECIFIED",
          "SECURITY_EVENT_SEVERITY_INFO",
          "SECURITY_EVENT_SEVERITY_LOW",
          "SECURITY_EVENT_SEVERITY_MEDIUM",
          "SECURITY_EVENT_SEVERITY_HIGH",
          "SECURITY_EVENT_SEVERITY_CRITICAL"
        ],
        "default": "SECURITY_EVENT_SEVERITY_UNSPECIFIED",
        "description": "Severity rank for a security event, derived server-side from nature (low numeric\nvalue = low severity, high numeric value = high severity)."
      },
      "SecurityEventSourceItem": {
        "type": "object",
        "properties": {
          "itemId": {
            "type": "string",
            "description": "Stable identifier of the source item within its event cluster."
          },
          "title": {
            "type": "string",
            "description": "Title of the article or OSINT record."
          },
          "link": {
            "type": "string",
            "description": "External URL to the source article."
          },
          "sourceType": {
            "type": "string",
            "description": "Source category (e.g. blog, news, dark-web, social)."
          },
          "publishedDate": {
            "type": "string",
            "format": "date-time",
            "description": "When the source was published."
          },
          "originatingParty": {
            "type": "string",
            "description": "Originating party named in this source item, when present."
          },
          "affectedParties": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Companies named as affected in this source item."
          },
          "sourceReliability": {
            "type": "number",
            "format": "float",
            "description": "Reliability score of the source, on a 0.0-1.0 scale; absent when not computed."
          }
        },
        "description": "A supporting OSINT or article record tying an organization to a security event.",
        "required": [
          "itemId",
          "title",
          "link",
          "sourceType",
          "publishedDate",
          "affectedParties"
        ]
      },
      "SecurityEventSubtype": {
        "type": "string",
        "enum": [
          "SECURITY_EVENT_SUBTYPE_UNSPECIFIED",
          "SECURITY_EVENT_SUBTYPE_BREACH",
          "SECURITY_EVENT_SUBTYPE_ALLEGED_BREACH",
          "SECURITY_EVENT_SUBTYPE_HACKER_CHATTER"
        ],
        "default": "SECURITY_EVENT_SUBTYPE_UNSPECIFIED",
        "description": "Fine-grained subclassification within a SecurityEventNature."
      },
      "SecurityEventSummary": {
        "type": "object",
        "properties": {
          "eventId": {
            "type": "string",
            "description": "Stable identifier for this event row. Pass through to GetSecurityEvent's\nor GetImpactedCompanies' event_id for detail lookups."
          },
          "organizationDomain": {
            "type": "string",
            "description": "Originating-party domain for this event row."
          },
          "nature": {
            "$ref": "#/components/schemas/SecurityEventNature"
          },
          "subtype": {
            "$ref": "#/components/schemas/SecurityEventSubtype"
          },
          "title": {
            "type": "string",
            "description": "Human-readable headline shown in the feed."
          },
          "sourceCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of distinct sources contributing evidence for this event."
          },
          "firstDetectedDate": {
            "type": "string",
            "format": "date-time",
            "description": "When the event was first detected (UTC)."
          },
          "eventDate": {
            "type": "string",
            "format": "date-time",
            "description": "Primary event instant for display; absent when not available."
          },
          "status": {
            "$ref": "#/components/schemas/SecurityEventVrmStatus"
          },
          "lastUpdatedDate": {
            "type": "string",
            "format": "date-time",
            "description": "When cluster evidence last changed (UTC)."
          },
          "impactedCompanies": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/security_event.v1.Organization"
            },
            "description": "Sample of impacted companies with identity and logo."
          },
          "impactedCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of monitored vendors assessed as impacted for this event in the caller's context."
          },
          "notImpactedCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of monitored vendors assessed as not impacted for this event."
          },
          "impactedUnknownCount": {
            "type": "integer",
            "format": "int32",
            "description": "Number of monitored vendors whose impacted status is unknown or not yet determined."
          },
          "severity": {
            "$ref": "#/components/schemas/SecurityEventSeverity"
          },
          "publishedDate": {
            "type": "string",
            "format": "date-time",
            "description": "When the first source was published; absent when not available."
          },
          "archivedDate": {
            "type": "string",
            "format": "date-time",
            "description": "When the event was archived for the caller's organization; absent while not archived."
          }
        },
        "description": "Summary row for the org-scoped security events feed (GetSecurityEventsFeed).",
        "required": [
          "eventId",
          "organizationDomain",
          "nature",
          "subtype",
          "title",
          "sourceCount",
          "firstDetectedDate",
          "status",
          "lastUpdatedDate",
          "impactedCompanies",
          "impactedCount",
          "notImpactedCount",
          "impactedUnknownCount"
        ]
      },
      "SecurityEventTimelineEntry": {
        "type": "object",
        "properties": {
          "kind": {
            "$ref": "#/components/schemas/SecurityEventTimelineEntryKind"
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time",
            "description": "When this entry happened (event creation time, or source ingestion time)."
          },
          "actor": {
            "type": "string",
            "description": "Originating party for SOURCE entries (e.g. \"BleepingComputer\"); absent for EVENT entries."
          },
          "description": {
            "type": "string",
            "description": "Source title for SOURCE entries; cluster title for EVENT entries."
          },
          "nature": {
            "$ref": "#/components/schemas/SecurityEventNature"
          },
          "subtype": {
            "$ref": "#/components/schemas/SecurityEventSubtype"
          }
        },
        "description": "One row on the security event timeline rail.",
        "required": [
          "kind",
          "occurredAt",
          "description"
        ]
      },
      "SecurityEventTimelineEntryKind": {
        "type": "string",
        "enum": [
          "SECURITY_EVENT_TIMELINE_ENTRY_KIND_UNSPECIFIED",
          "SECURITY_EVENT_TIMELINE_ENTRY_KIND_EVENT",
          "SECURITY_EVENT_TIMELINE_ENTRY_KIND_SOURCE"
        ],
        "default": "SECURITY_EVENT_TIMELINE_ENTRY_KIND_UNSPECIFIED",
        "description": "Kind of entry on the security event timeline rail.\n\n - SECURITY_EVENT_TIMELINE_ENTRY_KIND_EVENT: Aggregate event marker (event creation in platform).\n - SECURITY_EVENT_TIMELINE_ENTRY_KIND_SOURCE: Per-source ingestion entry."
      },
      "SecurityEventVendorDetail": {
        "type": "object",
        "properties": {
          "impactReasoning": {
            "$ref": "#/components/schemas/SecurityEventImpactReasoning"
          },
          "vrmRequests": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SecurityEventVrmRequest"
            },
            "description": "VRM response requests sent to this vendor, in chronological order."
          },
          "vendorStatus": {
            "$ref": "#/components/schemas/SecurityEventVendorStatus"
          },
          "communicationLog": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SecurityEventActivityEntry"
            },
            "description": "Chronological workflow activity log for this vendor on the event. See\nSecurityEventActivityType for what is (and is not) represented here."
          }
        },
        "description": "Vendor-perspective detail payload for a single vendor on a security event\n(GetVendorSecurityEventDetail).",
        "required": [
          "impactReasoning",
          "vrmRequests",
          "vendorStatus",
          "communicationLog"
        ]
      },
      "SecurityEventVendorStatus": {
        "type": "string",
        "enum": [
          "SECURITY_EVENT_VENDOR_STATUS_UNSPECIFIED",
          "SECURITY_EVENT_VENDOR_STATUS_ACTIVE",
          "SECURITY_EVENT_VENDOR_STATUS_TRIAGED",
          "SECURITY_EVENT_VENDOR_STATUS_RESPONSE_NEEDED",
          "SECURITY_EVENT_VENDOR_STATUS_REOPENED",
          "SECURITY_EVENT_VENDOR_STATUS_ARCHIVED",
          "SECURITY_EVENT_VENDOR_STATUS_RETRACTED"
        ],
        "default": "SECURITY_EVENT_VENDOR_STATUS_UNSPECIFIED",
        "description": "Vendor-side workflow status for a security event, from the perspective of the\nvendor named in GetVendorSecurityEventDetail.\n\n - SECURITY_EVENT_VENDOR_STATUS_ACTIVE: Vendor has been notified; event is awaiting initial triage.\n - SECURITY_EVENT_VENDOR_STATUS_TRIAGED: Vendor has acknowledged and triaged the event.\n - SECURITY_EVENT_VENDOR_STATUS_RESPONSE_NEEDED: A response has been requested from the vendor and is pending.\n - SECURITY_EVENT_VENDOR_STATUS_REOPENED: Event was previously closed but has been reopened for the vendor.\n - SECURITY_EVENT_VENDOR_STATUS_ARCHIVED: Event has been archived for the vendor; no further action expected.\n - SECURITY_EVENT_VENDOR_STATUS_RETRACTED: Upstream evidence source withdrew the underlying observation for the vendor."
      },
      "SecurityEventView": {
        "type": "string",
        "enum": [
          "SECURITY_EVENT_VIEW_UNSPECIFIED",
          "SECURITY_EVENT_VIEW_VRM",
          "SECURITY_EVENT_VIEW_VENDOR"
        ],
        "default": "SECURITY_EVENT_VIEW_UNSPECIFIED",
        "description": "Caller perspective for reading a security event: the VRM (customer) view or the\nvendor-facing view."
      },
      "SecurityEventVrmRequest": {
        "type": "object",
        "properties": {
          "organization": {
            "$ref": "#/components/schemas/security_event.v1.Organization"
          },
          "sentAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the request was sent."
          },
          "isInitialRequest": {
            "type": "boolean",
            "description": "True for the initial request; false for follow-up requests."
          },
          "customMessage": {
            "type": "string",
            "description": "Optional custom message included in the request template."
          }
        },
        "description": "One VRM response request sent to a vendor for a security event.",
        "required": [
          "organization",
          "sentAt",
          "isInitialRequest"
        ]
      },
      "SecurityEventVrmStatus": {
        "type": "string",
        "enum": [
          "SECURITY_EVENT_VRM_STATUS_UNSPECIFIED",
          "SECURITY_EVENT_VRM_STATUS_ACTIVE",
          "SECURITY_EVENT_VRM_STATUS_INVESTIGATING",
          "SECURITY_EVENT_VRM_STATUS_CLOSED",
          "SECURITY_EVENT_VRM_STATUS_REOPENED",
          "SECURITY_EVENT_VRM_STATUS_ARCHIVED",
          "SECURITY_EVENT_VRM_STATUS_RETRACTED"
        ],
        "default": "SECURITY_EVENT_VRM_STATUS_UNSPECIFIED",
        "description": "VRM (caller-organization) lifecycle status of a security event.\n\n - SECURITY_EVENT_VRM_STATUS_RETRACTED: Upstream evidence source withdrew the underlying observation; the event was\nnot user-resolved, the evidence itself was retracted."
      },
      "SendQuestionnaireBody": {
        "type": "object",
        "description": "Request to dispatch an already-created questionnaire to its vendor."
      },
      "SendQuestionnaireResponse": {
        "type": "object",
        "properties": {
          "questionnaire": {
            "$ref": "#/components/schemas/Questionnaire"
          }
        },
        "description": "Response containing the questionnaire after dispatch.",
        "required": [
          "questionnaire"
        ]
      },
      "SortOrder": {
        "type": "string",
        "enum": [
          "SORT_ORDER_UNSPECIFIED",
          "SORT_ORDER_ASC",
          "SORT_ORDER_DESC"
        ],
        "default": "SORT_ORDER_UNSPECIFIED",
        "description": "Sort direction for list and search APIs: ascending, descending, or unspecified."
      },
      "Status": {
        "type": "object",
        "properties": {
          "code": {
            "type": "integer",
            "format": "int32"
          },
          "message": {
            "type": "string"
          },
          "details": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Any"
            }
          }
        },
        "required": [
          "code",
          "message",
          "details"
        ]
      },
      "StringList": {
        "type": "object",
        "properties": {
          "values": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "Ordered list of string tokens, typically for IN-style or multi-select filter matches.",
        "required": [
          "values"
        ]
      },
      "SubmitVendorResponseRequest": {
        "type": "object",
        "properties": {
          "orgDomain": {
            "type": "string",
            "description": "Domain of the organization the security event belongs to."
          },
          "eventId": {
            "type": "string",
            "description": "Unique identifier of the security event."
          },
          "impactStatus": {
            "$ref": "#/components/schemas/SecurityEventImpactStatus"
          },
          "impactStatement": {
            "type": "string",
            "description": "Free-form description of the organizational impact."
          },
          "comment": {
            "type": "string",
            "description": "Optional comment from the vendor."
          }
        },
        "description": "Input for submitting a vendor response to a security event. The responding\nvendor's domain is derived from the caller's own organization domain claim.",
        "required": [
          "orgDomain",
          "eventId",
          "impactStatus",
          "impactStatement"
        ]
      },
      "SubmitVendorResponseResponse": {
        "type": "object",
        "properties": {
          "activity": {
            "$ref": "#/components/schemas/SecurityEventActivityEntry"
          }
        },
        "description": "Outcome of submitting a vendor response: the persisted activity entry.",
        "required": [
          "activity"
        ]
      },
      "UpdateVendorBody": {
        "type": "object",
        "properties": {
          "companyName": {
            "type": "string",
            "description": "Display name of the vendor company. Applied only if \"company_name\" is in update_mask."
          },
          "vendorId": {
            "type": "string",
            "description": "Customer-defined free-text identifier for the vendor. Applied only if\n\"vendor_id\" is in update_mask."
          },
          "isMonitored": {
            "type": "boolean",
            "description": "Whether the vendor should be actively monitored. Applied only if\n\"is_monitored\" is in update_mask."
          },
          "riskLevel": {
            "$ref": "#/components/schemas/RiskLevel"
          },
          "businessImpact": {
            "$ref": "#/components/schemas/BusinessImpact"
          },
          "dataTypesShared": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DataTypeShared"
            },
            "description": "Categories of data shared with the vendor. Replaces the existing set; applied\nonly if \"data_types_shared\" is in update_mask."
          },
          "accessTypes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccessType"
            },
            "description": "Types of access granted to the vendor. Replaces the existing set; applied\nonly if \"access_types\" is in update_mask."
          },
          "contractValue": {
            "type": "string",
            "format": "int64",
            "description": "Monetary value of the contract, in the minor units of the customer account's\ncurrency — same representation as Vendor.contract_value. Applied only if\n\"contract_value\" is in update_mask."
          },
          "contractEndDate": {
            "type": "string",
            "format": "date-time",
            "description": "Date the vendor contract expires. Applied only if \"contract_end_date\" is in\nupdate_mask; unset clears it."
          },
          "dataRegion": {
            "$ref": "#/components/schemas/DataRegion"
          },
          "updateMask": {
            "type": "string",
            "description": "Field paths (from the fields above, by their public JSON/proto name) to apply\nfrom this request. Required and must be non-empty: a field not listed here is\nignored even if set on the request. Naming an unknown or non-updatable path\n(e.g. \"domain_name\", \"lifecycle_status\") is rejected with INVALID_ARGUMENT."
          }
        },
        "description": "Writable, curated subset for partially updating a vendor in the caller's\ndirectory, plus the field mask that scopes the merge.\n\nDeliberately narrow, mirroring CreateVendorRequest: it has NO\ncustomer_organization_id — the organization is derived server-side from the\ncaller's access token — and no internal ids, audit actors, or contact PII.\ndomain_name and lifecycle_status are intentionally absent: domain_name is\nimmutable, and lifecycle transitions go through OffboardVendor instead.\n\nOnly the field paths named in update_mask are applied; a value left unset on a\nmasked field clears it (where the underlying field is optional/nullable).\nFields not named in update_mask are ignored even if set on the request.",
        "required": [
          "dataTypesShared",
          "accessTypes",
          "contractEndDate",
          "updateMask"
        ]
      },
      "UpdateVendorResponse": {
        "type": "object",
        "properties": {
          "vendor": {
            "$ref": "#/components/schemas/vendor.v1.Vendor"
          }
        },
        "description": "Response containing the updated vendor.",
        "required": [
          "vendor"
        ]
      },
      "VendorConnectionDetails": {
        "type": "object",
        "properties": {
          "description": {
            "type": "string"
          },
          "evidence": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "description": "Human-readable summary plus the raw evidence fragments that justify a single vendor\nconnection. The producer derives the description from the underlying detection (e.g.\n\"HTTP Request: fonts.googleapis.com\", \"Detected library: Bootstrap 3.3.7 via\ngetbootstrap.com\"); each evidence string is a raw fragment (request host, DNS target, SAN,\ncookie domain, ...) captured verbatim for UI display or downstream re-parsing.",
        "required": [
          "description",
          "evidence"
        ]
      },
      "VendorConnectionRelationship": {
        "type": "string",
        "enum": [
          "VENDOR_CONNECTION_RELATIONSHIP_UNSPECIFIED",
          "VENDOR_CONNECTION_RELATIONSHIP_THIRD_PARTY",
          "VENDOR_CONNECTION_RELATIONSHIP_FOURTH_PARTY"
        ],
        "default": "VENDOR_CONNECTION_RELATIONSHIP_UNSPECIFIED",
        "description": "Degree of separation between the customer and the detected vendor. Producers may leave this\nUNSPECIFIED while THIRD_PARTY is the only relationship currently emitted; FOURTH_PARTY is\nreserved for the upcoming nested-vendor classification work."
      },
      "VendorConnectionType": {
        "type": "string",
        "enum": [
          "VENDOR_CONNECTION_TYPE_UNSPECIFIED",
          "VENDOR_CONNECTION_TYPE_HTTP_REQUEST",
          "VENDOR_CONNECTION_TYPE_DETECTED_LIBRARY",
          "VENDOR_CONNECTION_TYPE_DNS",
          "VENDOR_CONNECTION_TYPE_BREACH",
          "VENDOR_CONNECTION_TYPE_PRODUCTS_DETECTED",
          "VENDOR_CONNECTION_TYPE_TLS",
          "VENDOR_CONNECTION_TYPE_X509"
        ],
        "default": "VENDOR_CONNECTION_TYPE_UNSPECIFIED",
        "description": "Channel on which a customer <-> vendor connection was detected (HTTP request, DNS, TLS,\nX509, ...). Mapping from the producer's per-channel evidence (e.g. bluepipe's detection\nchannels) into this consumer-facing grouping happens in the producer."
      },
      "VendorGroup": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Server-generated unique identifier of the group (the internal vendor_group_id,\nrenamed for the public surface exactly as Vendor.id curates the internal\nvendor_relationship_id). Pass this back when addressing a specific group."
          },
          "name": {
            "type": "string",
            "description": "Human-readable display name of the group; unique within the caller's organization."
          },
          "description": {
            "type": "string",
            "description": "Free-text description of the group. Absent when never set, which is\ndistinguishable from an explicitly empty description."
          },
          "memberCount": {
            "type": "string",
            "format": "int64",
            "description": "Number of vendors currently in this group. Maintained by the service and\nread-only on this surface. Typed int64 to match the internal counterpart, so the\ncurating builder copies the value across rather than narrowing it."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "Time the group was created."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Time the group's metadata was last updated."
          }
        },
        "description": "A vendor group in the caller's vendor directory, curated for public API consumers.\nA vendor group is the customer's own named collection over the third parties they\ntrack (e.g. by business unit or risk tier).\n\nA deliberately narrow, stable subset of the internal\nfactor_protos.vendor_relationship.v1.VendorGroup. Message field numbers are scoped\nto this message and renumbered densely on the public side, independent of the\ninternal contract. Intentionally excluded:\n  customer_organization_id – necessarily the caller's own org (the query is scoped\n                             to it server-side), so echoing it back adds nothing\n                             and leaks an internal id shape.\n  organizational_unit_id   – an internal scoping mechanism, not a customer-facing\n                             concept.\n  created_by / updated_by  – internal audit subject identifiers; the same exclusion\n                             the curated public Vendor makes.",
        "required": [
          "id",
          "name",
          "memberCount",
          "createdAt",
          "updatedAt"
        ]
      },
      "VendorLifecycleStatus": {
        "type": "string",
        "enum": [
          "VENDOR_LIFECYCLE_STATUS_UNSPECIFIED",
          "VENDOR_LIFECYCLE_STATUS_NEW",
          "VENDOR_LIFECYCLE_STATUS_ONBOARDED",
          "VENDOR_LIFECYCLE_STATUS_OFFBOARDED",
          "VENDOR_LIFECYCLE_STATUS_UNVETTED"
        ],
        "default": "VENDOR_LIFECYCLE_STATUS_UNSPECIFIED",
        "description": "Lifecycle state of a vendor as exposed on the public API. Curated public copy of\nthe internal factor_protos.vendor_relationship.v1.VendorLifecycleStatus.\n\nOrdinals are deliberately kept IDENTICAL to the internal enum (including a\n`reserved` slot for the internal-only DELETED). Rationale: unlike message field\nnumbers — which are scoped to a single message and are renumbered freely on the\npublic side — enum values can cross the public/internal boundary by their numeric\nvalue (e.g. a value cast or copied through a shared downstream service / read\nmodel). If the numbers diverged, a public value could silently decode as a\ndifferent internal one (e.g. public UNVETTED=4 landing on internal DELETED=4).\nValue *names* may differ (public uses the prefixed form); only the NUMBERS must\nstay aligned. When the internal enum gains a value, mirror it here at the same\nordinal — or `reserved` that ordinal if it stays internal-only.\n\n - VENDOR_LIFECYCLE_STATUS_UNSPECIFIED: Default zero value; lifecycle status was not set.\n - VENDOR_LIFECYCLE_STATUS_NEW: Newly added vendor, not yet onboarded.\n - VENDOR_LIFECYCLE_STATUS_ONBOARDED: Vendor is active and monitored.\n - VENDOR_LIFECYCLE_STATUS_OFFBOARDED: Vendor has been offboarded (archived).\n - VENDOR_LIFECYCLE_STATUS_UNVETTED: Tracked but not monitored: holds metadata only, consumes no monitoring slot.\nKept at 5 to match the internal ordinal."
      },
      "VendorPortfolio": {
        "type": "object",
        "properties": {
          "portfolioId": {
            "type": "string",
            "description": "Unique identifier of the portfolio."
          },
          "portfolioName": {
            "type": "string",
            "description": "Human-readable display name of the portfolio."
          }
        },
        "description": "A single portfolio a vendor belongs to. Curated public copy of the internal\nfactor_protos.vendor_relationship.v1.VendorRelationshipPortfolio.",
        "required": [
          "portfolioId",
          "portfolioName"
        ]
      },
      "VendorScoreResult": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string",
            "description": "The vendor domain these scores belong to."
          },
          "topLevelScore": {
            "$ref": "#/components/schemas/PublicVendorScore"
          },
          "breachLikelihoodScore": {
            "$ref": "#/components/schemas/PublicVendorScore"
          },
          "ransomwareScore": {
            "$ref": "#/components/schemas/PublicVendorScore"
          }
        },
        "description": "Overall, breach-likelihood, and ransomware scores for a single vendor domain. Any score not\navailable for the domain is left unset rather than defaulting to a zero/UNSPECIFIED value.",
        "required": [
          "domain"
        ]
      },
      "VulnerabilityDetail": {
        "type": "object",
        "properties": {
          "cveId": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "source": {
            "type": "string",
            "title": "\"<https://www.cvedetails.com/cve-assigners-cnas/1.html>\""
          },
          "cvssScores": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CvssScore"
            },
            "title": "\"a set of different CVSS structs, unique by version\""
          },
          "cwes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CweData"
            }
          },
          "cpes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "epss": {
            "type": "number",
            "format": "float",
            "title": "\"scaled from 0 to 1 <https://www.cvedetails.com/epss/faq.html>\""
          },
          "epssHistory": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EpssHistory"
            }
          },
          "published": {
            "type": "string",
            "format": "date-time"
          },
          "updated": {
            "type": "string",
            "format": "date-time"
          },
          "isInCisaKev": {
            "type": "boolean"
          }
        },
        "title": "/ VulnerabilityDetail class",
        "required": [
          "cveId",
          "title",
          "description",
          "source",
          "cvssScores",
          "cwes",
          "cpes",
          "epss",
          "epssHistory",
          "published",
          "updated",
          "isInCisaKev"
        ]
      },
      "observation.v1.Organization": {
        "type": "object",
        "properties": {
          "orn": {
            "type": "string",
            "title": "\"ORN to the organization\""
          },
          "scorecardOrn": {
            "type": "string",
            "title": "\"ORN to the scorecard\""
          },
          "displayName": {
            "type": "string",
            "title": "\"friendly name for rendering\""
          },
          "logoIcon": {
            "type": "string",
            "title": "\"url to the logo icon\""
          },
          "domain": {
            "type": "string",
            "title": "top-level domain"
          }
        },
        "title": "/ Organization class",
        "required": [
          "orn",
          "scorecardOrn",
          "displayName",
          "logoIcon",
          "domain"
        ]
      },
      "observation.v1.Vendor": {
        "type": "object",
        "properties": {
          "organization": {
            "$ref": "#/components/schemas/observation.v1.Organization"
          }
        },
        "title": "/ Vendor class",
        "required": [
          "organization"
        ]
      },
      "security_event.v1.Organization": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string",
            "description": "Top-level domain identifying the organization."
          },
          "displayName": {
            "type": "string",
            "description": "Friendly display name for rendering; absent when not yet resolved."
          },
          "logoIcon": {
            "type": "string",
            "description": "URL to the organization's logo icon; absent when not available."
          }
        },
        "description": "Minimal organization identity used throughout the security-events public API\n(impacted companies, VRM requesters, activity actors). Self-contained curated\ncopy — does not reference the public/observation domain's Organization message.",
        "required": [
          "domain"
        ]
      },
      "v1.Contact": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "description": "Email address to receive the remediation-request email."
          }
        },
        "description": "A single contact to receive a remediation-request email.",
        "required": [
          "email"
        ]
      },
      "vendor.v1.Vendor": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier of the vendor."
          },
          "domainName": {
            "type": "string",
            "description": "Primary domain name of the vendor."
          },
          "companyName": {
            "type": "string",
            "description": "Display name of the vendor company."
          },
          "companyIndustryCategory": {
            "type": "string",
            "description": "Industry category of the vendor company."
          },
          "companyLogoUrl": {
            "type": "string",
            "description": "URL of the vendor company logo."
          },
          "lifecycleStatus": {
            "$ref": "#/components/schemas/VendorLifecycleStatus"
          },
          "isMonitored": {
            "type": "boolean",
            "description": "Whether the vendor is actively monitored."
          },
          "dataRegion": {
            "$ref": "#/components/schemas/DataRegion"
          },
          "riskLevel": {
            "$ref": "#/components/schemas/RiskLevel"
          },
          "dataTypesShared": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DataTypeShared"
            },
            "description": "Categories of data shared with the vendor."
          },
          "businessImpact": {
            "$ref": "#/components/schemas/BusinessImpact"
          },
          "vendorId": {
            "type": "string",
            "description": "Customer-defined free-text identifier for the vendor (not the internal entity ID)."
          },
          "accessTypes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccessType"
            },
            "description": "Types of access granted to the vendor."
          },
          "contractValue": {
            "type": "string",
            "format": "int64",
            "description": "Monetary value of the contract, in the minor units of the customer account's\ncurrency (e.g. cents for a USD account). Currency is the caller's account\ncurrency; there is no per-vendor currency override."
          },
          "contractEndDate": {
            "type": "string",
            "format": "date-time",
            "description": "Date the vendor contract expires; absent when not set."
          },
          "lastAssessedDate": {
            "type": "string",
            "format": "date-time",
            "description": "Date the vendor was last assessed/reviewed; absent when never assessed."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the vendor was created."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the vendor was last updated."
          }
        },
        "description": "A vendor in the caller's vendor directory, curated for public API consumers.\nA deliberately narrow, stable subset of the internal vendor-relationship model —\ninternal ids, audit actors, and contact PII are intentionally excluded.",
        "required": [
          "id",
          "domainName",
          "lifecycleStatus",
          "isMonitored",
          "dataTypesShared",
          "accessTypes",
          "contractEndDate",
          "lastAssessedDate",
          "createdAt",
          "updatedAt"
        ]
      }
    }
  }
}