{
  "openapi": "3.0.3",
  "info": {
    "title": "AutoCISO Public API - Off-boarding and On-boarding",
    "version": "1.1.0",
    "description": "Read-only reconciliation of leaver (off-boarding) cases: which access to which applications\nhas been revoked, is still outstanding, or contradicts a completed task; and of joiner\n(on-boarding) cases: which required access has been granted, is still pending, or was\nconfirmed by a person.\n\nAuthenticate with an API token in the `Authorization: Bearer` header only. The token needs the\n`jml:read` scope. Name and email of employees are personal data and are returned only when the\ntoken also holds `pii:read`. Tokens are for server-side use.\n\nTreat every case response as pseudonymised personal data under your own data-protection\nrules: even without `pii:read`, a case carries an employee ID, a masked email, department,\njob title and employment dates, which identify a person in a small company. The item\nendpoints carry only the employee ID.\n\nThe API is read-only. Creating or changing cases, marking items done, access profiles, due\ndates and cancelling a case happen in the console only; API tokens cannot do them. There is\nno free-text search: you cannot filter on name or email. A token holding `pii:read` alone\nreaches no endpoint here, because every endpoint needs `jml:read`.\n\nEvery successful response is `{ data, error: null, meta }`. Timestamps are UTC (RFC 3339);\n`meta.accessDataAsOf` is the latest access detection time that was used and is not a scan time\nor a freshness guarantee. Requests against an unknown path return a plain-text 404 that is\nnot part of this contract.\n"
  },
  "servers": [
    {
      "url": "https://api.autociso.io/api/v1",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Off-boarding",
      "description": "Leaver cases. Treat every case response as pseudonymised personal data (employee ID, masked email, department, job title and dates identify a person in a small company); the item endpoints carry only the employee ID."
    },
    {
      "name": "On-boarding",
      "description": "Joiner cases. Treat every case response as pseudonymised personal data (employee ID, masked email, department, job title and dates identify a person in a small company); the item endpoints carry only the employee ID."
    },
    {
      "name": "SBOMs"
    },
    {
      "name": "Findings"
    },
    {
      "name": "Vendors"
    },
    {
      "name": "Supplier questionnaires",
      "description": "Questionnaire templates for supplier security assessments, their versions and drafts. A questionnaire\nhas one published version and at most one open draft; a token reads them, prepares a draft and may\nsubmit it for approval, and a person publishes.\n\n**Refused for tokens.** These routes are not operations of this API: every token, whatever its\nscopes, gets `403 HUMAN_APPROVAL_REQUIRED` on `publish`, `reject`, `archive`, `unarchive` and\n`default` under `/supplier-assessment-templates/{templateId}`, and on deleting a questionnaire\n(`DELETE /supplier-assessment-templates/{templateId}`). Publishing changes the score of every new\nassessment and cannot be recalled, so a person does it in the console. Likewise a token cannot\nacknowledge lowering a critical finding severity.\n"
    },
    {
      "name": "API Tokens"
    },
    {
      "name": "Health"
    },
    {
      "name": "access"
    },
    {
      "name": "asset"
    },
    {
      "name": "audittrail"
    },
    {
      "name": "compliance"
    },
    {
      "name": "employee"
    },
    {
      "name": "iso"
    },
    {
      "name": "monitor"
    },
    {
      "name": "risk"
    },
    {
      "name": "supplier"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/jml/offboarding/cases": {
      "get": {
        "operationId": "listOffboardingCases",
        "summary": "List leaver cases",
        "description": "Lists leaver (off-boarding) cases with a reconciled summary of their items. Requires the jml:read scope; employee name and email are returned only for tokens that also hold pii:read, which are subject to a per-token request window (429 RATE_LIMITED).",
        "tags": [
          "Off-boarding"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "jml:read",
        "x-required-feature": "lifecycle_workflows",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size. Default 25, maximum 100; a larger value is rejected with 400 VALIDATION_FAILED.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Zero-based offset. Maximum 100000.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000,
              "default": 0
            }
          },
          {
            "name": "sort[openedAt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "filter[status][eq]",
            "in": "query",
            "required": false,
            "description": "Case status. CANCELLED cases are excluded unless an eq or in filter names CANCELLED.",
            "schema": {
              "type": "string",
              "enum": [
                "OPEN",
                "IN_PROGRESS",
                "COMPLETED",
                "CANCELLED"
              ]
            }
          },
          {
            "name": "filter[status][ne]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "OPEN",
                "IN_PROGRESS",
                "COMPLETED",
                "CANCELLED"
              ]
            }
          },
          {
            "name": "filter[status][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "maxItems": 100,
              "items": {
                "type": "string",
                "enum": [
                  "OPEN",
                  "IN_PROGRESS",
                  "COMPLETED",
                  "CANCELLED"
                ]
              }
            }
          },
          {
            "name": "filter[employeeId][eq]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^empl_[A-Za-z0-9_-]{1,59}$"
            }
          },
          {
            "name": "filter[employeeId][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "maxItems": 100,
              "items": {
                "type": "string",
                "pattern": "^empl_[A-Za-z0-9_-]{1,59}$"
              }
            }
          },
          {
            "name": "filter[openedAt][gt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[openedAt][gte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[openedAt][lt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[openedAt][lte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[dueAt][gt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[dueAt][gte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[dueAt][lt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[dueAt][lte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The response is never cached.",
            "headers": {
              "Cache-Control": {
                "description": "Always no-store.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseListResponse"
                },
                "examples": {
                  "withoutPii": {
                    "$ref": "#/components/examples/CaseListWithoutPii"
                  },
                  "withPii": {
                    "$ref": "#/components/examples/CaseListWithPii"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/jml/offboarding/cases/{caseId}": {
      "get": {
        "operationId": "getOffboardingCase",
        "summary": "Get a leaver case",
        "description": "Returns one leaver case with its reconciled summary. Items are read with the case items operation.",
        "tags": [
          "Off-boarding"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "jml:read",
        "x-required-feature": "lifecycle_workflows",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "required": true,
            "description": "Leaver case id (lfc_...). An unknown, foreign or malformed id returns the same 404.",
            "schema": {
              "type": "string",
              "pattern": "^lfc_[A-Za-z0-9_-]{1,59}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The response is never cached.",
            "headers": {
              "Cache-Control": {
                "description": "Always no-store.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseResponse"
                },
                "examples": {
                  "withoutPii": {
                    "$ref": "#/components/examples/CaseWithoutPii"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/jml/offboarding/cases/{caseId}/items": {
      "get": {
        "operationId": "listOffboardingCaseItems",
        "summary": "List the items of a leaver case",
        "description": "Lists the reconciled items of one leaver case. meta.summary counts the whole filtered set before pagination.",
        "tags": [
          "Off-boarding"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "jml:read",
        "x-required-feature": "lifecycle_workflows",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "required": true,
            "description": "Leaver case id (lfc_...). An unknown, foreign or malformed id returns the same 404.",
            "schema": {
              "type": "string",
              "pattern": "^lfc_[A-Za-z0-9_-]{1,59}$"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size. Default 25, maximum 100; a larger value is rejected with 400 VALIDATION_FAILED.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Zero-based offset. Maximum 100000.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000,
              "default": 0
            }
          },
          {
            "name": "filter[status][eq]",
            "in": "query",
            "required": false,
            "description": "Reconciled item status.",
            "schema": {
              "type": "string",
              "enum": [
                "REVOKED",
                "OUTSTANDING",
                "DISCREPANCY",
                "ATTESTED"
              ]
            }
          },
          {
            "name": "filter[status][ne]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "REVOKED",
                "OUTSTANDING",
                "DISCREPANCY",
                "ATTESTED"
              ]
            }
          },
          {
            "name": "filter[status][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "maxItems": 100,
              "items": {
                "type": "string",
                "enum": [
                  "REVOKED",
                  "OUTSTANDING",
                  "DISCREPANCY",
                  "ATTESTED"
                ]
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The response is never cached.",
            "headers": {
              "Cache-Control": {
                "description": "Always no-store.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemListResponse"
                },
                "examples": {
                  "items": {
                    "$ref": "#/components/examples/ItemList"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/jml/offboarding/items": {
      "get": {
        "operationId": "listOffboardingItems",
        "summary": "List leaver items across cases (feed)",
        "description": "Flat feed of reconciled leaver items across cases, for polling. By default items of COMPLETED cases are included alongside OPEN and IN_PROGRESS ones (only CANCELLED cases are excluded unless named in a caseStatus filter), unlike the on-boarding feed, which defaults to OPEN and IN_PROGRESS. Use itemKey as the stable deduplication key. A result set above the server limit returns 422 QUERY_TOO_BROAD. Concurrent feed requests are limited per organisation; excess requests return 429 RATE_LIMITED with Retry-After: 1.",
        "tags": [
          "Off-boarding"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "jml:read",
        "x-required-feature": "lifecycle_workflows",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size. Default 25, maximum 100; a larger value is rejected with 400 VALIDATION_FAILED.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Zero-based offset. Maximum 100000.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000,
              "default": 0
            }
          },
          {
            "name": "sort[openedAt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort[assetName]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "filter[status][eq]",
            "in": "query",
            "required": false,
            "description": "Reconciled item status.",
            "schema": {
              "type": "string",
              "enum": [
                "REVOKED",
                "OUTSTANDING",
                "DISCREPANCY",
                "ATTESTED"
              ]
            }
          },
          {
            "name": "filter[status][ne]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "REVOKED",
                "OUTSTANDING",
                "DISCREPANCY",
                "ATTESTED"
              ]
            }
          },
          {
            "name": "filter[status][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "maxItems": 100,
              "items": {
                "type": "string",
                "enum": [
                  "REVOKED",
                  "OUTSTANDING",
                  "DISCREPANCY",
                  "ATTESTED"
                ]
              }
            }
          },
          {
            "name": "filter[caseStatus][eq]",
            "in": "query",
            "required": false,
            "description": "Status of the owning case. CANCELLED cases are excluded unless named.",
            "schema": {
              "type": "string",
              "enum": [
                "OPEN",
                "IN_PROGRESS",
                "COMPLETED",
                "CANCELLED"
              ]
            }
          },
          {
            "name": "filter[caseStatus][ne]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "OPEN",
                "IN_PROGRESS",
                "COMPLETED",
                "CANCELLED"
              ]
            }
          },
          {
            "name": "filter[caseStatus][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "maxItems": 100,
              "items": {
                "type": "string",
                "enum": [
                  "OPEN",
                  "IN_PROGRESS",
                  "COMPLETED",
                  "CANCELLED"
                ]
              }
            }
          },
          {
            "name": "filter[employeeId][eq]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^empl_[A-Za-z0-9_-]{1,59}$"
            }
          },
          {
            "name": "filter[employeeId][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "maxItems": 100,
              "items": {
                "type": "string",
                "pattern": "^empl_[A-Za-z0-9_-]{1,59}$"
              }
            }
          },
          {
            "name": "filter[assetId][eq]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(ast_[A-Za-z0-9_-]{1,59}|[0-9a-f]{24})$"
            }
          },
          {
            "name": "filter[assetId][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "maxItems": 100,
              "items": {
                "type": "string",
                "pattern": "^(ast_[A-Za-z0-9_-]{1,59}|[0-9a-f]{24})$"
              }
            }
          },
          {
            "name": "filter[caseId][eq]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^lfc_[A-Za-z0-9_-]{1,59}$"
            }
          },
          {
            "name": "filter[openedAt][gte]",
            "in": "query",
            "required": false,
            "description": "Opening time of the owning case.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[openedAt][lte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[taskCompletedAt][gte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[taskCompletedAt][lte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The response is never cached.",
            "headers": {
              "Cache-Control": {
                "description": "Always no-store.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ItemListResponse"
                },
                "examples": {
                  "items": {
                    "$ref": "#/components/examples/ItemList"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/QueryTooBroad"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/jml/onboarding/cases": {
      "get": {
        "operationId": "listOnboardingCases",
        "summary": "List joiner cases",
        "description": "Lists joiner (on-boarding) cases with a reconciled summary of their items: GRANTED when the access is detected in the inventory, ATTESTED when a person confirmed it, else PENDING. Requires the jml:read scope; employee name and email are returned only for tokens that also hold pii:read, which are subject to a per-token request window (429 RATE_LIMITED).",
        "tags": [
          "On-boarding"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "jml:read",
        "x-required-feature": "lifecycle_workflows",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size. Default 25, maximum 100; a larger value is rejected with 400 VALIDATION_FAILED.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Zero-based offset. Maximum 100000.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000,
              "default": 0
            }
          },
          {
            "name": "sort[openedAt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort[dueAt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "filter[status][eq]",
            "in": "query",
            "required": false,
            "description": "Case status. CANCELLED cases are excluded unless an eq or in filter names CANCELLED.",
            "schema": {
              "type": "string",
              "enum": [
                "OPEN",
                "IN_PROGRESS",
                "COMPLETED",
                "CANCELLED"
              ]
            }
          },
          {
            "name": "filter[status][ne]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "OPEN",
                "IN_PROGRESS",
                "COMPLETED",
                "CANCELLED"
              ]
            }
          },
          {
            "name": "filter[status][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "maxItems": 100,
              "items": {
                "type": "string",
                "enum": [
                  "OPEN",
                  "IN_PROGRESS",
                  "COMPLETED",
                  "CANCELLED"
                ]
              }
            }
          },
          {
            "name": "filter[employeeId][eq]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^empl_[A-Za-z0-9_-]{1,59}$"
            }
          },
          {
            "name": "filter[employeeId][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "maxItems": 100,
              "items": {
                "type": "string",
                "pattern": "^empl_[A-Za-z0-9_-]{1,59}$"
              }
            }
          },
          {
            "name": "filter[openedAt][gt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[openedAt][gte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[openedAt][lt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[openedAt][lte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[dueAt][gt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[dueAt][gte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[dueAt][lt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[dueAt][lte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The response is never cached.",
            "headers": {
              "Cache-Control": {
                "description": "Always no-store.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardingCaseListResponse"
                },
                "examples": {
                  "withoutPii": {
                    "$ref": "#/components/examples/OnboardingCaseListWithoutPii"
                  },
                  "withPii": {
                    "$ref": "#/components/examples/OnboardingCaseListWithPii"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/jml/onboarding/cases/{caseId}": {
      "get": {
        "operationId": "getOnboardingCase",
        "summary": "Get a joiner case",
        "description": "Returns one joiner case with its reconciled summary. Items are read with the case items operation. employee.employeeStatus shows the current status, for example TERMINATED when the joiner has left since.",
        "tags": [
          "On-boarding"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "jml:read",
        "x-required-feature": "lifecycle_workflows",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "required": true,
            "description": "Joiner case id (lfc_...). An unknown, foreign, leaver or malformed id returns the same 404.",
            "schema": {
              "type": "string",
              "pattern": "^lfc_[A-Za-z0-9_-]{1,59}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The response is never cached.",
            "headers": {
              "Cache-Control": {
                "description": "Always no-store.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardingCaseResponse"
                },
                "examples": {
                  "withoutPii": {
                    "$ref": "#/components/examples/OnboardingCaseWithoutPii"
                  },
                  "notReady": {
                    "$ref": "#/components/examples/OnboardingCaseNotReady"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/jml/onboarding/cases/{caseId}/items": {
      "get": {
        "operationId": "listOnboardingCaseItems",
        "summary": "List the items of a joiner case",
        "description": "Lists the reconciled items of one joiner case. The status is evaluated at read time: an item turns GRANTED as soon as the access is detected, without any change to the case. meta.summary counts the whole filtered set before pagination.",
        "tags": [
          "On-boarding"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "jml:read",
        "x-required-feature": "lifecycle_workflows",
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "required": true,
            "description": "Joiner case id (lfc_...). An unknown, foreign, leaver or malformed id returns the same 404.",
            "schema": {
              "type": "string",
              "pattern": "^lfc_[A-Za-z0-9_-]{1,59}$"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size. Default 25, maximum 100; a larger value is rejected with 400 VALIDATION_FAILED.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Zero-based offset. Maximum 100000.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000,
              "default": 0
            }
          },
          {
            "name": "filter[status][eq]",
            "in": "query",
            "required": false,
            "description": "Reconciled item status.",
            "schema": {
              "type": "string",
              "enum": [
                "GRANTED",
                "PENDING",
                "ATTESTED"
              ]
            }
          },
          {
            "name": "filter[status][ne]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "GRANTED",
                "PENDING",
                "ATTESTED"
              ]
            }
          },
          {
            "name": "filter[status][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "maxItems": 100,
              "items": {
                "type": "string",
                "enum": [
                  "GRANTED",
                  "PENDING",
                  "ATTESTED"
                ]
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The response is never cached.",
            "headers": {
              "Cache-Control": {
                "description": "Always no-store.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardingItemListResponse"
                },
                "examples": {
                  "items": {
                    "$ref": "#/components/examples/OnboardingItemList"
                  },
                  "pending": {
                    "$ref": "#/components/examples/OnboardingItemListPending"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/jml/onboarding/items": {
      "get": {
        "operationId": "listOnboardingItems",
        "summary": "List joiner items across cases (feed)",
        "description": "Flat feed of reconciled joiner items across cases, for polling. By default only items of OPEN and IN_PROGRESS cases are returned; an eq or in filter on caseStatus replaces that default. Use itemKey as the stable deduplication key. A result set above the server limit returns 422 QUERY_TOO_BROAD. Concurrent feed requests are limited per organisation; excess requests return 429 RATE_LIMITED with Retry-After: 1.",
        "tags": [
          "On-boarding"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "jml:read",
        "x-required-feature": "lifecycle_workflows",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size. Default 25, maximum 100; a larger value is rejected with 400 VALIDATION_FAILED.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Zero-based offset. Maximum 100000.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000,
              "default": 0
            }
          },
          {
            "name": "sort[openedAt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort[assetName]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "filter[status][eq]",
            "in": "query",
            "required": false,
            "description": "Reconciled item status.",
            "schema": {
              "type": "string",
              "enum": [
                "GRANTED",
                "PENDING",
                "ATTESTED"
              ]
            }
          },
          {
            "name": "filter[status][ne]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "GRANTED",
                "PENDING",
                "ATTESTED"
              ]
            }
          },
          {
            "name": "filter[status][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "maxItems": 100,
              "items": {
                "type": "string",
                "enum": [
                  "GRANTED",
                  "PENDING",
                  "ATTESTED"
                ]
              }
            }
          },
          {
            "name": "filter[caseStatus][eq]",
            "in": "query",
            "required": false,
            "description": "Status of the owning case. Default: OPEN and IN_PROGRESS; an eq or in filter replaces the default, a ne filter narrows it.",
            "schema": {
              "type": "string",
              "enum": [
                "OPEN",
                "IN_PROGRESS",
                "COMPLETED",
                "CANCELLED"
              ]
            }
          },
          {
            "name": "filter[caseStatus][ne]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "OPEN",
                "IN_PROGRESS",
                "COMPLETED",
                "CANCELLED"
              ]
            }
          },
          {
            "name": "filter[caseStatus][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "maxItems": 100,
              "items": {
                "type": "string",
                "enum": [
                  "OPEN",
                  "IN_PROGRESS",
                  "COMPLETED",
                  "CANCELLED"
                ]
              }
            }
          },
          {
            "name": "filter[employeeId][eq]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^empl_[A-Za-z0-9_-]{1,59}$"
            }
          },
          {
            "name": "filter[employeeId][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "maxItems": 100,
              "items": {
                "type": "string",
                "pattern": "^empl_[A-Za-z0-9_-]{1,59}$"
              }
            }
          },
          {
            "name": "filter[assetId][eq]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(ast_[A-Za-z0-9_-]{1,59}|[0-9a-f]{24})$"
            }
          },
          {
            "name": "filter[assetId][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "maxItems": 100,
              "items": {
                "type": "string",
                "pattern": "^(ast_[A-Za-z0-9_-]{1,59}|[0-9a-f]{24})$"
              }
            }
          },
          {
            "name": "filter[caseId][eq]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^lfc_[A-Za-z0-9_-]{1,59}$"
            }
          },
          {
            "name": "filter[openedAt][gte]",
            "in": "query",
            "required": false,
            "description": "Opening time of the owning case.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[openedAt][lte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[dueAt][gte]",
            "in": "query",
            "required": false,
            "description": "Due date of the owning case.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[dueAt][lte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success. The response is never cached.",
            "headers": {
              "Cache-Control": {
                "description": "Always no-store.",
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardingItemListResponse"
                },
                "examples": {
                  "items": {
                    "$ref": "#/components/examples/OnboardingItemList"
                  },
                  "pending": {
                    "$ref": "#/components/examples/OnboardingItemListPending"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "422": {
            "$ref": "#/components/responses/QueryTooBroad"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/sscs/sboms": {
      "get": {
        "operationId": "listSboms",
        "summary": "List SBOMs",
        "description": "List every SBOM in the organization. `q` does a case-insensitive substring match on the SBOM name. Results are not paginated. Requires the sbom:read scope.",
        "tags": [
          "SBOMs"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "sbom:read",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Case-insensitive substring match on the SBOM name.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "All SBOMs of the organization; an empty array when there are none.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SbomListResponse"
                },
                "examples": {
                  "list": {
                    "$ref": "#/components/examples/SbomList"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/SscsUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SscsFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SscsForbidden"
          },
          "429": {
            "$ref": "#/components/responses/SscsRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SscsInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SscsServiceUnavailable"
          }
        }
      },
      "post": {
        "operationId": "createSbom",
        "summary": "Create SBOM",
        "description": "Register an SBOM record without uploading a manifest, for example when components are attached by a later process. `source` is forced to `manual`; `sbomId` and `orgId` are server-assigned and sending them is rejected. Requires the sbom:write scope (or a signed-in Owner or Manager session).",
        "tags": [
          "SBOMs"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "sbom:write",
        "x-required-feature": "supply_chain_security",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SbomCreateRequest"
              },
              "examples": {
                "minimal": {
                  "value": {
                    "name": "example-service",
                    "version": "2026.9.1",
                    "repoUrl": "https://git.example.com/example-org/example-service",
                    "branch": "main"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created SBOM.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SbomResponse"
                },
                "examples": {
                  "created": {
                    "$ref": "#/components/examples/SbomCreated"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SscsBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SscsUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SscsFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SscsForbidden"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/SscsRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SscsInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SscsServiceUnavailable"
          }
        }
      }
    },
    "/sscs/sboms/upload": {
      "post": {
        "operationId": "uploadSbom",
        "x-doc-slug": "sboms/upload",
        "summary": "Upload SBOM manifest",
        "description": "Upload a dependency manifest as `multipart/form-data`. The file is parsed, an SBOM and its\ncomponents are stored, and CVE matching starts in the background: the response returns\nbefore matching finishes, so the finding counts are zero here and populate shortly after.\n\nAccepted filenames: `go.sum`, `pom.xml`, `build.gradle`, `build.gradle.kts`,\n`package.json`, `requirements.txt`. The parser is chosen from the base filename, not the\nextension. The body limit is 5 MB; a larger body returns 413 FILE_TOO_LARGE.\n\nRequires the sbom:write scope (or a signed-in Owner or Manager session).\n",
        "tags": [
          "SBOMs"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "sbom:write",
        "x-required-feature": "supply_chain_security",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/SbomUploadForm"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created SBOM; source is the detected manifest type.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SbomResponse"
                },
                "examples": {
                  "uploaded": {
                    "$ref": "#/components/examples/SbomUploaded"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/UploadBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SscsUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SscsFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SscsForbidden"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/SscsRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SscsInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SscsServiceUnavailable"
          }
        }
      }
    },
    "/sscs/sboms/{sbomId}": {
      "get": {
        "operationId": "getSbom",
        "summary": "Get SBOM",
        "description": "Fetch one SBOM by id, including its component count and the per-severity finding counts refreshed by the last CVE matching run. Requires the sbom:read scope.",
        "tags": [
          "SBOMs"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "sbom:read",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/SbomId"
          }
        ],
        "responses": {
          "200": {
            "description": "The SBOM.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SbomResponse"
                },
                "examples": {
                  "sbom": {
                    "$ref": "#/components/examples/SbomOne"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/SscsUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SscsFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SscsForbidden"
          },
          "404": {
            "$ref": "#/components/responses/SbomNotFound"
          },
          "429": {
            "$ref": "#/components/responses/SscsRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SscsInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SscsServiceUnavailable"
          }
        }
      },
      "delete": {
        "operationId": "deleteSbom",
        "summary": "Delete SBOM",
        "description": "Delete an SBOM together with its components and every vulnerability finding raised against it. Findings are removed first, so the operation leaves no orphans. Requires the sbom:write scope (or a signed-in Owner or Manager session).",
        "tags": [
          "SBOMs"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "sbom:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/SbomId"
          }
        ],
        "responses": {
          "200": {
            "description": "The SBOM, its components and its findings were deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletedResponse"
                },
                "examples": {
                  "deleted": {
                    "value": {
                      "data": {
                        "deleted": true
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/SscsUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SscsFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SscsForbidden"
          },
          "404": {
            "$ref": "#/components/responses/SbomNotFound"
          },
          "429": {
            "$ref": "#/components/responses/SscsRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SscsInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SscsServiceUnavailable"
          }
        }
      }
    },
    "/sscs/sboms/{sbomId}/components": {
      "get": {
        "operationId": "listSbomComponents",
        "x-doc-slug": "sboms/list-components",
        "summary": "List SBOM components",
        "description": "List the resolved components of one SBOM. Ownership of the SBOM is verified before any component is returned, so an id from another organization yields 404, never another tenant's data. Requires the sbom:read scope.",
        "tags": [
          "SBOMs"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "sbom:read",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/SbomId"
          }
        ],
        "responses": {
          "200": {
            "description": "The components of the SBOM; an empty array when there are none.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ComponentListResponse"
                },
                "examples": {
                  "components": {
                    "$ref": "#/components/examples/ComponentList"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/SscsUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SscsFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SscsForbidden"
          },
          "404": {
            "$ref": "#/components/responses/SbomNotFound"
          },
          "429": {
            "$ref": "#/components/responses/SscsRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SscsInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SscsServiceUnavailable"
          }
        }
      }
    },
    "/sscs/findings": {
      "get": {
        "operationId": "listFindings",
        "summary": "List findings",
        "description": "List vulnerability findings. `status` defaults to `open`: pass it explicitly to see anything else. An unrecognised `status` or `severity` is rejected with 400, not silently ignored. `sbomId` narrows the result to one SBOM. Results are not paginated. Requires the sbom:read scope.",
        "tags": [
          "Findings"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "sbom:read",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Finding status. Defaults to open.",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "mitigated",
                "accepted_risk",
                "false_positive",
                "fixed"
              ],
              "default": "open"
            }
          },
          {
            "name": "severity",
            "in": "query",
            "required": false,
            "description": "Severity filter (upper case).",
            "schema": {
              "type": "string",
              "enum": [
                "CRITICAL",
                "HIGH",
                "MEDIUM",
                "LOW"
              ]
            }
          },
          {
            "name": "sbomId",
            "in": "query",
            "required": false,
            "description": "Only findings raised against this SBOM.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching findings; an empty array when there are none.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FindingListResponse"
                },
                "examples": {
                  "findings": {
                    "$ref": "#/components/examples/FindingList"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/FindingsBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SscsUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SscsFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SscsForbidden"
          },
          "429": {
            "$ref": "#/components/responses/SscsRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SscsInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SscsServiceUnavailable"
          }
        }
      }
    },
    "/sscs/findings/summary": {
      "get": {
        "operationId": "getFindingsSummary",
        "x-doc-slug": "findings/summary",
        "summary": "Findings summary",
        "description": "Counts of open findings grouped by severity: the number behind a dashboard tile. Findings in any other status are excluded and the endpoint takes no filters. Requires the sbom:read scope.",
        "tags": [
          "Findings"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "sbom:read",
        "x-required-feature": "supply_chain_security",
        "responses": {
          "200": {
            "description": "Open finding counts per severity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SeveritySummaryResponse"
                },
                "examples": {
                  "summary": {
                    "value": {
                      "data": {
                        "critical": 1,
                        "high": 4,
                        "medium": 11,
                        "low": 6
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/SscsUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SscsFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SscsForbidden"
          },
          "429": {
            "$ref": "#/components/responses/SscsRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SscsInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SscsServiceUnavailable"
          }
        }
      }
    },
    "/sscs/findings/{findingId}/status": {
      "patch": {
        "operationId": "updateFindingStatus",
        "x-doc-slug": "findings/update-status",
        "summary": "Update finding status",
        "description": "Move a finding through its triage workflow. `status` is required and must be one of open, mitigated, accepted_risk, false_positive, fixed. `remediationNotes` is optional free text recording the decision. Requires the sbom:write scope (or a signed-in Owner or Manager session).",
        "tags": [
          "Findings"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "sbom:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/FindingId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FindingStatusRequest"
              },
              "examples": {
                "mitigated": {
                  "value": {
                    "status": "mitigated",
                    "remediationNotes": "Upgraded the dependency in release 2026.9.2."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The status was updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdatedResponse"
                },
                "examples": {
                  "updated": {
                    "value": {
                      "data": {
                        "updated": true
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/FindingStatusBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SscsUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SscsFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SscsForbidden"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/SscsRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SscsInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SscsServiceUnavailable"
          }
        }
      }
    },
    "/sscs/vendors": {
      "get": {
        "operationId": "listVendors",
        "summary": "List vendors",
        "description": "List every tracked software vendor. Takes no filters and is not paginated. Requires the sbom:read scope.",
        "tags": [
          "Vendors"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "sbom:read",
        "x-required-feature": "supply_chain_security",
        "responses": {
          "200": {
            "description": "All vendors of the organization; an empty array when there are none.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VendorListResponse"
                },
                "examples": {
                  "vendors": {
                    "$ref": "#/components/examples/VendorList"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/SscsUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SscsFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SscsForbidden"
          },
          "429": {
            "$ref": "#/components/responses/SscsRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SscsInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SscsServiceUnavailable"
          }
        }
      },
      "post": {
        "operationId": "createVendor",
        "summary": "Create vendor",
        "description": "Register a software vendor. `name`, `type`, `riskTier` and `assessmentStatus` are all required. `type` is oss, commercial or internal; `riskTier` is the integer 1, 2 or 3 (1 is the highest risk); `assessmentStatus` is not_started, in_progress or completed. `vendorId` and `orgId` are server-assigned. Requires the sbom:write scope (or a signed-in Owner or Manager session).",
        "tags": [
          "Vendors"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "sbom:write",
        "x-required-feature": "supply_chain_security",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VendorRequest"
              },
              "examples": {
                "commercial": {
                  "value": {
                    "name": "Example Analytics",
                    "website": "https://vendor.example.com",
                    "type": "commercial",
                    "riskTier": 2,
                    "assessmentStatus": "in_progress",
                    "notes": "Processes pseudonymised usage events only."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The created vendor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VendorResponse"
                },
                "examples": {
                  "created": {
                    "$ref": "#/components/examples/VendorOne"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SscsBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SscsUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SscsFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SscsForbidden"
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/SscsRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SscsInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SscsServiceUnavailable"
          }
        }
      }
    },
    "/sscs/vendors/risk-summary": {
      "get": {
        "operationId": "getVendorRiskSummary",
        "x-doc-slug": "vendors/risk-summary",
        "summary": "Vendor risk summary",
        "description": "Open findings aggregated per vendor: the third-party risk view. Only vendors with at least one open finding appear, so an empty array means no vendor-linked component is currently vulnerable. Requires the sbom:read scope.",
        "tags": [
          "Vendors"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "sbom:read",
        "x-required-feature": "supply_chain_security",
        "responses": {
          "200": {
            "description": "Open finding counts per vendor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VendorRiskSummaryListResponse"
                },
                "examples": {
                  "summary": {
                    "value": {
                      "data": [
                        {
                          "vendorId": "vendor_example000001",
                          "critical": 0,
                          "high": 2,
                          "medium": 1,
                          "low": 0,
                          "total": 3
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/SscsUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SscsFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SscsForbidden"
          },
          "429": {
            "$ref": "#/components/responses/SscsRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SscsInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SscsServiceUnavailable"
          }
        }
      }
    },
    "/sscs/vendors/{vendorId}": {
      "put": {
        "operationId": "updateVendor",
        "summary": "Update vendor",
        "description": "Update a vendor. The body is validated against the same schema as create, so all four required fields must be present: send the full record, not a partial patch. `website` and `notes` are always overwritten with what you send (omit them to clear); `name`, `type`, `riskTier` and `assessmentStatus` are overwritten when non-empty. Requires the sbom:write scope (or a signed-in Owner or Manager session).",
        "tags": [
          "Vendors"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "sbom:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/VendorId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VendorRequest"
              },
              "examples": {
                "reassessed": {
                  "value": {
                    "name": "Example Analytics",
                    "website": "https://vendor.example.com",
                    "type": "commercial",
                    "riskTier": 1,
                    "assessmentStatus": "completed",
                    "notes": "Annual review closed."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated vendor.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VendorResponse"
                },
                "examples": {
                  "updated": {
                    "$ref": "#/components/examples/VendorOne"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SscsBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SscsUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SscsFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SscsForbidden"
          },
          "404": {
            "description": "Unknown or foreign-tenant vendor id. code NOT_FOUND.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SscsErrorEnvelope"
                },
                "examples": {
                  "notFound": {
                    "value": {
                      "data": null,
                      "error": {
                        "id": "EH8T6RC",
                        "code": "NOT_FOUND",
                        "message": "vendor not found"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "$ref": "#/components/responses/PayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/SscsRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SscsInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SscsServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates": {
      "get": {
        "operationId": "listSupplierTemplates",
        "x-doc-slug": "supplier-templates/list",
        "summary": "List supplier questionnaires",
        "description": "List the questionnaires of the organization, newest change first: the built-in questionnaire\n(always the first row of an unfiltered first page) and every authored version, drafts\nincluded. A row carries no sections; read one questionnaire to get its content.\nRequires the supplier_template:read scope.\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:read",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/Limit"
          },
          {
            "$ref": "#/components/parameters/Offset"
          },
          {
            "name": "sort[status]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "sort[updatedAt]",
            "in": "query",
            "required": false,
            "description": "Default order is updatedAt descending.",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            }
          },
          {
            "name": "filter[status][eq]",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/TemplateStatus"
            }
          },
          {
            "name": "filter[status][ne]",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/TemplateStatus"
            }
          },
          {
            "name": "filter[status][in]",
            "in": "query",
            "required": false,
            "style": "form",
            "explode": false,
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/TemplateStatus"
              }
            }
          },
          {
            "name": "filter[source][eq]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "builtin",
                "authored"
              ]
            }
          },
          {
            "name": "filter[templateKey][eq]",
            "in": "query",
            "required": false,
            "description": "All versions of one questionnaire.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "filter[isDefault][eq]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "filter[updatedAt][gt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[updatedAt][gte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[updatedAt][lt]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "filter[updatedAt][lte]",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One page of questionnaires; an empty array when none match. meta.total counts all matches.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateListResponse"
                },
                "examples": {
                  "list": {
                    "$ref": "#/components/examples/TemplateList"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadQuery"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SupplierTemplatesForbidden"
          },
          "429": {
            "$ref": "#/components/responses/SupplierTemplatesRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      },
      "post": {
        "operationId": "createSupplierTemplate",
        "x-doc-slug": "supplier-templates/create",
        "summary": "Create a questionnaire",
        "description": "Create a new, empty questionnaire as a draft with one section. `name` is required and may\nbe given in `en`, `ru` and `he`; `en` is required. `firstSectionTitle` names the first\nsection (`Section 1` when omitted). `templateId`, sections and ids are assigned by the server and sending them is\nrejected. An `If-Match` header is rejected with 400 VALIDATION_FAILED.\n\nAn organization can hold 50 questionnaires; over that the answer is\n409 TEMPLATE_LIMIT_REACHED. Structural write: 30 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateCreateRequest"
              },
              "examples": {
                "minimal": {
                  "value": {
                    "name": {
                      "en": "Example vendor security review"
                    },
                    "firstSectionTitle": {
                      "en": "Governance"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The new draft. The ETag header carries its revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponse"
                },
                "examples": {
                  "created": {
                    "$ref": "#/components/examples/TemplateDraftNew"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SupplierTemplatesBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "409": {
            "$ref": "#/components/responses/TemplateLimitConflict"
          },
          "413": {
            "$ref": "#/components/responses/SupplierTemplatesPayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/clone": {
      "post": {
        "operationId": "cloneSupplierTemplate",
        "x-doc-slug": "supplier-templates/clone",
        "summary": "Clone a questionnaire",
        "description": "Copy an existing questionnaire into a new draft of a new questionnaire. `sourceTemplateId`\nis the built-in questionnaire or a `templateId` of the organization (an unknown or foreign\nid is 404 NOT_FOUND); `name` is the new name (`en` required); `setAsDefault` marks the\ncopy as the organization default. An `If-Match` header is rejected with 400 VALIDATION_FAILED.\n\nCounts toward the 50 questionnaires per organization (409 TEMPLATE_LIMIT_REACHED).\nStructural write: 30 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateCloneRequest"
              },
              "examples": {
                "builtin": {
                  "value": {
                    "sourceTemplateId": "satpl_builtin_supplier_security_privacy_v1",
                    "name": {
                      "en": "Example vendor security review"
                    },
                    "setAsDefault": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The new draft, with the content of the source. The ETag header carries its revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponse"
                },
                "examples": {
                  "cloned": {
                    "$ref": "#/components/examples/TemplateDraftNew"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SupplierTemplatesBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "404": {
            "$ref": "#/components/responses/TemplateNotFound"
          },
          "409": {
            "$ref": "#/components/responses/TemplateLimitConflict"
          },
          "413": {
            "$ref": "#/components/responses/SupplierTemplatesPayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}": {
      "get": {
        "operationId": "getSupplierTemplate",
        "x-doc-slug": "supplier-templates/get",
        "summary": "Get a questionnaire",
        "description": "Fetch one questionnaire version by `templateId` with its sections, questions, options and\nscoring fields (`weight`, `riskValue`, `findingSeverity`, `controlIds`), the structural\n`limits` and the `revision` to send with an edit. The built-in questionnaire can be read\nwith its fixed id `satpl_builtin_supplier_security_privacy_v1`. Requires the\nsupplier_template:read scope.\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:read",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "responses": {
          "200": {
            "description": "The questionnaire. The ETag header carries its revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponse"
                },
                "examples": {
                  "one": {
                    "$ref": "#/components/examples/TemplateDraft"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SupplierTemplatesForbidden"
          },
          "404": {
            "$ref": "#/components/responses/TemplateNotFound"
          },
          "429": {
            "$ref": "#/components/responses/SupplierTemplatesRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}/versions/{version}": {
      "get": {
        "operationId": "getSupplierTemplateVersion",
        "x-doc-slug": "supplier-templates/get-version",
        "summary": "Get a questionnaire version",
        "description": "Fetch one numbered version of a questionnaire. Unlike the other routes, the path segment\n`{templateId}` here is the questionnaire's `templateKey` (the same in every version), not a\n`templateId`. `meta.contentHashVerified` tells whether the stored content still matches\nthe hash recorded when the version was published; a mismatch is reported, never an error.\nA draft carries version 0. Requires the supplier_template:read scope.\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:read",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateKey"
          },
          {
            "$ref": "#/components/parameters/Version"
          }
        ],
        "responses": {
          "200": {
            "description": "The version, with meta.contentHashVerified.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateVersionResponse"
                },
                "examples": {
                  "version": {
                    "$ref": "#/components/examples/TemplateVersion"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadVersion"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SupplierTemplatesForbidden"
          },
          "404": {
            "$ref": "#/components/responses/TemplateNotFound"
          },
          "429": {
            "$ref": "#/components/responses/SupplierTemplatesRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}/versions/{version}/diff/{otherVersion}": {
      "get": {
        "operationId": "diffSupplierTemplateVersions",
        "x-doc-slug": "supplier-templates/diff-versions",
        "summary": "Compare two questionnaire versions",
        "description": "List what changed between two versions of one questionnaire: added, removed and modified\nquestions and options, with the before and after of each changed field. For a removed\nquestion, `referencedByAssessments` counts the existing assessments that hold an answer to\nit. As in get-version, `{templateId}` is the questionnaire's `templateKey`.\nRequires the supplier_template:read scope.\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:read",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateKey"
          },
          {
            "$ref": "#/components/parameters/Version"
          },
          {
            "name": "otherVersion",
            "in": "path",
            "required": true,
            "description": "The version to compare with.",
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The differences, an empty rows array when the versions are equal.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateDiffResponse"
                },
                "examples": {
                  "diff": {
                    "$ref": "#/components/examples/TemplateVersionDiff"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadVersion"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SupplierTemplatesForbidden"
          },
          "404": {
            "$ref": "#/components/responses/TemplateNotFound"
          },
          "429": {
            "$ref": "#/components/responses/SupplierTemplatesRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}/validate": {
      "post": {
        "operationId": "validateSupplierTemplate",
        "x-doc-slug": "supplier-templates/validate",
        "summary": "Validate a draft",
        "description": "Check the content of a questionnaire without changing anything and without a request body.\n`violations` (codes `V1` to `V12`) block submitting the draft for approval; `warnings`\n(`W1_NO_ZERO_RISK_OPTION` to `W5_ALL_OPTIONS_ZERO_RISK`) do not. It says whether the draft\nis publishable, not what publishing would change: use preview-publish for that.\nA read: requires the supplier_template:read scope.\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:read",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "responses": {
          "200": {
            "description": "The violations and warnings; both arrays are empty for a clean draft.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateValidateResponse"
                },
                "examples": {
                  "clean": {
                    "$ref": "#/components/examples/TemplateValidate"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SupplierTemplatesForbidden"
          },
          "404": {
            "$ref": "#/components/responses/TemplateNotFound"
          },
          "429": {
            "$ref": "#/components/responses/SupplierTemplatesRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}/publish/preview": {
      "post": {
        "operationId": "previewSupplierTemplatePublish",
        "x-doc-slug": "supplier-templates/preview-publish",
        "summary": "Preview publishing a draft",
        "description": "A dry run of publishing, without a request body and without any change: the scoring impact\nof the draft against the latest published version (the built-in questionnaire for a first\npublish), the same violations and warnings as validate plus the weight-raised warning\n`W6_WEIGHT_RAISED_3X`, and the permissions of the caller. Publishing itself is refused for\nevery token. A read: requires the supplier_template:read scope.\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:read",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "responses": {
          "200": {
            "description": "The impact ledger, violations, warnings and permissions.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplatePreviewResponse"
                },
                "examples": {
                  "preview": {
                    "$ref": "#/components/examples/TemplatePreview"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/SupplierTemplatesForbidden"
          },
          "404": {
            "$ref": "#/components/responses/TemplateNotFound"
          },
          "429": {
            "$ref": "#/components/responses/SupplierTemplatesRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}/draft": {
      "post": {
        "operationId": "openSupplierTemplateDraft",
        "x-doc-slug": "supplier-templates/open-draft",
        "summary": "Open a draft of a published questionnaire",
        "description": "Reopen a published version for editing: a new draft in the same questionnaire family with a\ncopy of its content (`version` 0, `parentVersion` the published version). No request body.\nOnly a published version can be reopened (409 NOT_A_DRAFT otherwise), and a family has at\nmost one open draft (409 DRAFT_EXISTS). The built-in questionnaire cannot be edited\n(403 BUILTIN_IMMUTABLE): clone it instead. Structural write: 30 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "responses": {
          "201": {
            "description": "The new draft. The ETag header carries its revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponse"
                },
                "examples": {
                  "draft": {
                    "$ref": "#/components/examples/TemplateDraftNew"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "404": {
            "$ref": "#/components/responses/TemplateNotFound"
          },
          "409": {
            "$ref": "#/components/responses/DraftConflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}/meta": {
      "patch": {
        "operationId": "patchSupplierTemplateMeta",
        "x-doc-slug": "supplier-templates/update-meta",
        "summary": "Edit the title, description and modes of a draft",
        "description": "Change the title, the description and the assessment modes of a draft. At least one field is\nrequired; a mode is a non-blank token of at most 64 characters. `title` and `description`\nreplace the whole localised object. Send the draft's `revision` in the body or as `If-Match`\n(optional here). An edit that changes nothing returns 200 and does not change the revision.\nOnly a draft can be edited: published, archived and submitted versions answer 409\n(TEMPLATE_PUBLISHED, TEMPLATE_ARCHIVED, TEMPLATE_SUBMITTED). Field edit: 120 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateMetaPatchRequest"
              },
              "examples": {
                "title": {
                  "value": {
                    "title": {
                      "en": "Example vendor security review",
                      "ru": "Пример анкеты безопасности поставщика"
                    },
                    "revision": 3
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated draft. The ETag header carries its revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponse"
                },
                "examples": {
                  "updated": {
                    "$ref": "#/components/examples/TemplateDraft"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SupplierTemplatesBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "404": {
            "$ref": "#/components/responses/TemplateNotFound"
          },
          "409": {
            "$ref": "#/components/responses/EditConflict"
          },
          "413": {
            "$ref": "#/components/responses/SupplierTemplatesPayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}/sections": {
      "post": {
        "operationId": "addSupplierTemplateSection",
        "x-doc-slug": "supplier-templates/add-section",
        "summary": "Add a section to a draft",
        "description": "Append an empty section to a draft. `title` (`en` required) and the draft's `revision` are\nrequired; `sectionId` and the order are assigned by the server. A draft can hold 20\nsections (409 SECTION_LIMIT_REACHED). Structural write: 30 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateSectionCreateRequest"
              },
              "examples": {
                "section": {
                  "value": {
                    "title": {
                      "en": "Access control"
                    },
                    "revision": 3
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The updated draft, including the new section. The ETag header carries its revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponse"
                },
                "examples": {
                  "added": {
                    "$ref": "#/components/examples/TemplateDraftWithSection"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SupplierTemplatesBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "404": {
            "$ref": "#/components/responses/TemplateNotFound"
          },
          "409": {
            "$ref": "#/components/responses/SectionConflict"
          },
          "413": {
            "$ref": "#/components/responses/SupplierTemplatesPayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}/sections/{sectionId}": {
      "patch": {
        "operationId": "renameSupplierTemplateSection",
        "x-doc-slug": "supplier-templates/rename-section",
        "summary": "Rename a section of a draft",
        "description": "Replace the title of a section (`title.en` required). The `revision` is optional and is\nhonoured when sent; a rename does not change it. A rename to the current title changes\nnothing and returns 200. Field edit: 120 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          },
          {
            "$ref": "#/components/parameters/SectionId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateSectionPatchRequest"
              },
              "examples": {
                "rename": {
                  "value": {
                    "title": {
                      "en": "Access management"
                    },
                    "revision": 4
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated draft. The ETag header carries its revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponse"
                },
                "examples": {
                  "renamed": {
                    "$ref": "#/components/examples/TemplateDraftRenamedSection"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SupplierTemplatesBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "404": {
            "$ref": "#/components/responses/SectionNotFound"
          },
          "409": {
            "$ref": "#/components/responses/EditConflict"
          },
          "413": {
            "$ref": "#/components/responses/SupplierTemplatesPayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      },
      "delete": {
        "operationId": "deleteSupplierTemplateSection",
        "x-doc-slug": "supplier-templates/delete-section",
        "summary": "Delete a section of a draft",
        "description": "Delete a section and its questions from a draft. The draft's `revision` is required, as an\n`If-Match` header or as `{\"revision\": N}` in an optional body of at most 4 KiB (otherwise\n400 VALIDATION_FAILED). The section cannot be deleted while a question in another section\ndepends on one of its questions (409 SECTION_REFERENCED, with the dependants in\n`error.args`), or while it holds the vendor-type question that other questions are gated on\n(409 QUESTION_IS_GATING_TRIGGER). Structural write: 30 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          },
          {
            "$ref": "#/components/parameters/SectionId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevisionRequest"
              },
              "examples": {
                "revision": {
                  "value": {
                    "revision": 4
                  }
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "The section is deleted. No body; the ETag header carries the new revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SupplierTemplatesBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "404": {
            "$ref": "#/components/responses/SectionNotFound"
          },
          "409": {
            "$ref": "#/components/responses/SectionConflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/translate": {
      "post": {
        "operationId": "translateSupplierTemplateField",
        "x-doc-slug": "supplier-templates/translate",
        "summary": "Translate one questionnaire field",
        "description": "Machine-translate one piece of questionnaire text into a target language. The call is stateless: it\nreads and saves nothing, and returns the text for the caller to write into a field with an edit\noperation. `sources` holds the text in the languages the caller has (`en`, `ru`, `he`, at most 2000\ncharacters each, HTML is rejected) and `target` is the language wanted; a source in the target\nlanguage is ignored. If no source in another language has text, the answer is\n422 NOTHING_TO_TRANSLATE. The translation is produced by an AI provider: 503 AI_UNAVAILABLE when none\nis configured and 502 AI_FAILED when the provider fails or returns nothing (retry later). Count it as a field edit:\n120 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "parameters": null,
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateTranslateRequest"
              },
              "examples": {
                "toRussian": {
                  "value": {
                    "sources": {
                      "en": "Do you encrypt data at rest?"
                    },
                    "target": "ru"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The translated text.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateTranslateResponse"
                },
                "examples": {
                  "translated": {
                    "$ref": "#/components/examples/TemplateTranslated"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SupplierTemplatesBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "413": {
            "$ref": "#/components/responses/SupplierTemplatesPayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/NothingToTranslate"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "502": {
            "$ref": "#/components/responses/TranslationFailed"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailableTranslate"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}/questions": {
      "post": {
        "operationId": "addSupplierTemplateQuestion",
        "x-doc-slug": "supplier-templates/add-question",
        "summary": "Add a question to a section of a draft",
        "description": "Append a question to a section of a draft. `sectionId`, `answerType` and `text` (`en` required) are\nrequired; `questionId` and the order are assigned by the server. A choice question\n(`single_select`, `multi_select`) must be created with 2 to 12 `options`, every other answer type with\nnone. `weight` is 1 to 10, `domain` one of the listed domains (or empty), `controlIds` and `modes` are\nfree tokens of at most 64 characters. The draft's `revision` is optional here; when sent (in the body\nor as `If-Match`) a stale value fails with 409 STALE_REVISION. A section holds 50 questions and a\nquestionnaire 300 (409 QUESTION_LIMIT_REACHED), and the document may not exceed 1 MiB\n(409 TEMPLATE_SIZE_LIMIT_REACHED). The question is added to the draft only; it is scored after a person\npublishes the draft. Structural write: 30 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateQuestionCreateRequest"
              },
              "examples": {
                "singleSelect": {
                  "value": {
                    "sectionId": "sect_1hgyun41rx4a",
                    "answerType": "single_select",
                    "text": {
                      "en": "Is data encrypted at rest?"
                    },
                    "required": true,
                    "modes": [],
                    "domain": "operations",
                    "weight": 5,
                    "options": [
                      {
                        "label": {
                          "en": "Yes, all stores"
                        },
                        "riskValue": 0
                      },
                      {
                        "label": {
                          "en": "No"
                        },
                        "riskValue": 4,
                        "findingSeverity": "high",
                        "finding": {
                          "en": "Data at rest is not encrypted."
                        }
                      }
                    ],
                    "revision": 3
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The updated draft, including the new question. The ETag header carries its revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponse"
                },
                "examples": {
                  "added": {
                    "$ref": "#/components/examples/TemplateDraftWithQuestion"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SupplierTemplatesBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "404": {
            "$ref": "#/components/responses/SectionNotFound"
          },
          "409": {
            "$ref": "#/components/responses/QuestionAddConflict"
          },
          "413": {
            "$ref": "#/components/responses/SupplierTemplatesPayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}/questions/{questionId}": {
      "patch": {
        "operationId": "patchSupplierTemplateQuestion",
        "x-doc-slug": "supplier-templates/update-question",
        "summary": "Edit a question of a draft",
        "description": "Change fields of one question of a draft: `text`, `help`, `evidenceHint` (each replaces the whole\nlocalised object), `answerType`, `required`, `modes`, `domain`, `weight`, `controlIds` and\n`allowNotApplicable`. At least one field is required. The question's id, its options and its gating\nrules are not editable here (use the option operations for options). A field edit is lock-free: it\ndoes not check or change the draft `revision` (a `revision` or `If-Match` sent with it is ignored),\nand an edit that changes nothing returns 200 and is not recorded. The edit does not re-check the whole questionnaire (for example a\nchoice question needs two options): run `validateSupplierTemplate`, which submit also runs. Only a draft\ncan be edited: published, archived and submitted versions answer 409 (TEMPLATE_PUBLISHED,\nTEMPLATE_ARCHIVED, TEMPLATE_SUBMITTED). Field edit: 120 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          },
          {
            "$ref": "#/components/parameters/QuestionId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateQuestionPatchRequest"
              },
              "examples": {
                "weight": {
                  "value": {
                    "weight": 8,
                    "required": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated draft. The ETag header carries its revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponse"
                },
                "examples": {
                  "updated": {
                    "$ref": "#/components/examples/TemplateDraftWithQuestion"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SupplierTemplatesBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "404": {
            "$ref": "#/components/responses/ContentNotFound"
          },
          "409": {
            "$ref": "#/components/responses/ContentConflict"
          },
          "413": {
            "$ref": "#/components/responses/SupplierTemplatesPayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      },
      "delete": {
        "operationId": "deleteSupplierTemplateQuestion",
        "x-doc-slug": "supplier-templates/delete-question",
        "summary": "Delete a question of a draft",
        "description": "Remove a question and its options from a draft. The draft's `revision` is optional: send it as an\n`If-Match` header or as `{\"revision\": N}` in an optional body of at most 4 KiB (otherwise\n400 VALIDATION_FAILED) and a stale value fails with 409 STALE_REVISION. The question cannot be deleted\nwhile another question's gating rule depends on it (409 QUESTION_REFERENCED, the dependants are in\n`error.args.dependents`), and the vendor-type (service-type) question that other questions are gated\non can never be deleted (409 QUESTION_IS_GATING_TRIGGER). Structural write: 30 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          },
          {
            "$ref": "#/components/parameters/QuestionId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevisionRequest"
              },
              "examples": {
                "revision": {
                  "value": {
                    "revision": 4
                  }
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "The question is deleted. No body; the ETag header carries the new revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SupplierTemplatesBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "404": {
            "$ref": "#/components/responses/QuestionNotFound"
          },
          "409": {
            "$ref": "#/components/responses/QuestionDeleteConflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}/questions/{questionId}/options": {
      "post": {
        "operationId": "addSupplierTemplateOption",
        "x-doc-slug": "supplier-templates/add-option",
        "summary": "Add an option to a choice question of a draft",
        "description": "Append an answer option to a `single_select` or `multi_select` question of a draft. `label` (`en`\nrequired), `riskValue` (0, no risk, to 4) and the draft's `revision` are required; `findingSeverity`\n(`info`, `low`, `medium`, `high`, `critical`, or empty), `finding` and `notApplicable` are optional.\n`optionId` is assigned by the server. Other answer types take no options\n(409 OPTIONS_NOT_ALLOWED), a question holds 12 options (409 OPTION_LIMIT_REACHED), and the document\nmay not exceed 1 MiB (409 TEMPLATE_SIZE_LIMIT_REACHED). Structural write: 30 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          },
          {
            "$ref": "#/components/parameters/QuestionId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateOptionCreateRequest"
              },
              "examples": {
                "option": {
                  "value": {
                    "label": {
                      "en": "Partly"
                    },
                    "riskValue": 2,
                    "findingSeverity": "medium",
                    "revision": 4
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The updated draft, including the new option. The ETag header carries its revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponse"
                },
                "examples": {
                  "added": {
                    "$ref": "#/components/examples/TemplateDraftWithOption"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SupplierTemplatesBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "404": {
            "$ref": "#/components/responses/QuestionNotFound"
          },
          "409": {
            "$ref": "#/components/responses/OptionAddConflict"
          },
          "413": {
            "$ref": "#/components/responses/SupplierTemplatesPayloadTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}/questions/{questionId}/options/{optionId}": {
      "patch": {
        "operationId": "patchSupplierTemplateOption",
        "x-doc-slug": "supplier-templates/update-option",
        "summary": "Edit an option of a draft question",
        "description": "Change fields of one answer option of a draft: `label`, `riskValue` (0 to 4), `findingSeverity`,\n`finding` and `notApplicable`. At least one field is required. A field edit is lock-free: it does not\ncheck or change the draft `revision`, and an edit that changes nothing returns 200 and is not recorded.\nClearing or lowering a `critical` finding severity lowers the score of every future assessment and\nneeds an acknowledgement a person gives with `acknowledgeRiskReduction`, `riskReductionReason` and\n`riskReductionJustification`. Without it the answer is 422 RISK_REDUCTION_NOT_ACKNOWLEDGED, and a token\nthat sends `acknowledgeRiskReduction: true` is refused with 403 HUMAN_APPROVAL_REQUIRED, so a token\ncannot lower a critical severity; a person does it in the console. Only a draft can be edited:\npublished, archived and submitted versions answer 409 (TEMPLATE_PUBLISHED, TEMPLATE_ARCHIVED,\nTEMPLATE_SUBMITTED). Field edit: 120 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          },
          {
            "$ref": "#/components/parameters/QuestionId"
          },
          {
            "$ref": "#/components/parameters/OptionId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateOptionPatchRequest"
              },
              "examples": {
                "risk": {
                  "value": {
                    "riskValue": 3,
                    "findingSeverity": "high"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated draft. The ETag header carries its revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponse"
                },
                "examples": {
                  "updated": {
                    "$ref": "#/components/examples/TemplateDraftWithQuestion"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SupplierTemplatesBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenOptionPatch"
          },
          "404": {
            "$ref": "#/components/responses/ContentNotFound"
          },
          "409": {
            "$ref": "#/components/responses/ContentConflict"
          },
          "413": {
            "$ref": "#/components/responses/SupplierTemplatesPayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/RiskReductionNotAcknowledged"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      },
      "delete": {
        "operationId": "deleteSupplierTemplateOption",
        "x-doc-slug": "supplier-templates/delete-option",
        "summary": "Delete an option of a draft question",
        "description": "Remove one answer option from a question of a draft. The draft's `revision` is required, as an\n`If-Match` header or as `{\"revision\": N}` in an optional body of at most 4 KiB (otherwise\n400 VALIDATION_FAILED). A choice question must keep two options (409 OPTION_MINIMUM_REACHED), and an\noption that another question's gating rule depends on cannot be deleted (409 OPTION_REFERENCED, the\ndependants are in `error.args.dependents`). Structural write: 30 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          },
          {
            "$ref": "#/components/parameters/QuestionId"
          },
          {
            "$ref": "#/components/parameters/OptionId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevisionRequest"
              },
              "examples": {
                "revision": {
                  "value": {
                    "revision": 5
                  }
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "The option is deleted. No body; the ETag header carries the new revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SupplierTemplatesBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "404": {
            "$ref": "#/components/responses/QuestionNotFound"
          },
          "409": {
            "$ref": "#/components/responses/OptionDeleteConflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}/submit": {
      "post": {
        "operationId": "submitSupplierTemplate",
        "x-doc-slug": "supplier-templates/submit",
        "summary": "Submit a draft for approval",
        "description": "Send a draft to the people who can publish it. The draft's `revision` is required (in the body or\nas `If-Match`; otherwise 400 VALIDATION_FAILED), so an approver is asked about exactly the version the\ncaller saw. `note` (at most 500 characters) is shown to the approver. The whole draft is validated\nfirst: if it has problems nothing changes, the status stays `draft` and the answer is\n422 TEMPLATE_INVALID with the list in `error.args.violations` (the same list as\n`validateSupplierTemplate`): for example a choice question with fewer than two options, or a question without English text. A submitted version is frozen until the submitter withdraws it\n(`withdrawSupplierTemplate`) or an approver sends it back. Publishing it as the next version is a\nperson's decision and is refused to tokens. The built-in questionnaire cannot be submitted\n(403 BUILTIN_IMMUTABLE). Structural write: 30 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          },
          {
            "$ref": "#/components/parameters/IfMatch"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TemplateSubmitRequest"
              },
              "examples": {
                "submit": {
                  "value": {
                    "revision": 3,
                    "note": "Added the encryption question."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The submitted version (status `submitted`). The ETag header carries its revision, which submitting does not change.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponse"
                },
                "examples": {
                  "submitted": {
                    "$ref": "#/components/examples/TemplateSubmitted"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/SupplierTemplatesBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "404": {
            "$ref": "#/components/responses/TemplateNotFound"
          },
          "409": {
            "$ref": "#/components/responses/SubmitConflict"
          },
          "413": {
            "$ref": "#/components/responses/SupplierTemplatesPayloadTooLarge"
          },
          "422": {
            "$ref": "#/components/responses/TemplateInvalid"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/supplier-assessment-templates/{templateId}/withdraw": {
      "post": {
        "operationId": "withdrawSupplierTemplate",
        "x-doc-slug": "supplier-templates/withdraw",
        "summary": "Withdraw a submitted draft",
        "description": "Return a version that is awaiting approval to `draft` so it can be edited again. No request body.\nOnly the person who submitted it can withdraw it, and a token acts as the person who created it: a\nwithdraw by anyone else answers 404 NOT_FOUND, the same as for a version that does not exist. A version\nthat is not awaiting approval answers 409 NOT_SUBMITTED (a draft), NOT_A_DRAFT (published) or\nTEMPLATE_ARCHIVED. Structural write: 30 per token and hour.\nRequires the supplier_template:write scope (or a signed-in Owner, Manager or Contributor session).\n",
        "tags": [
          "Supplier questionnaires"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "x-required-scope": "supplier_template:write",
        "x-required-feature": "supply_chain_security",
        "parameters": [
          {
            "$ref": "#/components/parameters/TemplateId"
          }
        ],
        "responses": {
          "200": {
            "description": "The draft again (status `draft`). The ETag header carries its revision.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TemplateResponse"
                },
                "examples": {
                  "withdrawn": {
                    "$ref": "#/components/examples/TemplateDraft"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/SupplierTemplatesUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/SupplierTemplatesFeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/ForbiddenWrite"
          },
          "404": {
            "$ref": "#/components/responses/TemplateNotFound"
          },
          "409": {
            "$ref": "#/components/responses/WithdrawConflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimitedWrite"
          },
          "500": {
            "$ref": "#/components/responses/SupplierTemplatesInternalError"
          },
          "503": {
            "$ref": "#/components/responses/SupplierTemplatesServiceUnavailable"
          }
        }
      }
    },
    "/tokens": {
      "get": {
        "operationId": "listTokens",
        "summary": "List API tokens",
        "description": "Every API token of the organization, including revoked ones (`revokedAt` set). The secret value is never returned after creation; `prefix` is the first visible characters, for recognising a token. Requires a console session of an Owner or Manager.",
        "tags": [
          "API Tokens"
        ],
        "security": [
          {
            "consoleSession": []
          }
        ],
        "x-auth": "session",
        "x-required-roles": [
          "owner",
          "manager"
        ],
        "responses": {
          "200": {
            "description": "All tokens of the organization; an empty array when there are none.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenListResponse"
                },
                "examples": {
                  "list": {
                    "$ref": "#/components/examples/TokenList"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/TokensUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TokensForbidden"
          },
          "500": {
            "$ref": "#/components/responses/TokensInternalError"
          }
        }
      },
      "post": {
        "operationId": "createToken",
        "summary": "Create an API token",
        "description": "Create a token with the given scopes. The response carries `tokenValue`, the secret, exactly once: store it in a secret manager, it cannot be shown again. Scopes are explicit catalogue names (`GET /tokens/scopes` lists them, with who may grant each and whether an expiry is required); a wildcard, a bundle name or an unknown scope is refused with SCOPE_INVALID. Some scopes are limited to an Owner (OWNER_REQUIRED), need an active membership (MEMBERSHIP_REQUIRED) or a sufficient role (INSUFFICIENT_ROLE), and some require an expiry within a maximum lifetime (EXPIRY_REQUIRED, EXPIRY_TOO_LONG): `pii:read` needs an Owner and expires within 90 days; `jml:read` expires within 365 days; `supplier_template:write` needs an expiry. A token cannot be created or revoked from a support session (SUPPORT_SESSION_NO_MINT). At most 20 tokens per organization. Requires a console session of an Owner or Manager.",
        "tags": [
          "API Tokens"
        ],
        "security": [
          {
            "consoleSession": []
          }
        ],
        "x-auth": "session",
        "x-required-roles": [
          "owner",
          "manager"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTokenRequest"
              },
              "examples": {
                "ci": {
                  "summary": "CI token that uploads SBOMs",
                  "value": {
                    "name": "GitHub Actions SBOM upload",
                    "scopes": [
                      "sbom:write"
                    ]
                  }
                },
                "leaverFeed": {
                  "summary": "Nightly leaver feed, expiring in a year",
                  "value": {
                    "name": "HR leaver sync",
                    "scopes": [
                      "jml:read"
                    ],
                    "expiresAt": "2027-10-01T00:00:00Z"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The token, with its secret value. This is the only time `tokenValue` is returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedTokenResponse"
                },
                "examples": {
                  "created": {
                    "$ref": "#/components/examples/CreatedToken"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/TokensBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/TokensUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/CreateForbidden"
          },
          "422": {
            "$ref": "#/components/responses/CreateRejected"
          },
          "500": {
            "$ref": "#/components/responses/TokensInternalError"
          }
        }
      }
    },
    "/tokens/scopes": {
      "get": {
        "operationId": "listTokenScopes",
        "summary": "List assignable token scopes",
        "description": "The scope catalogue used by the token dialog: every scope that POST /tokens accepts, its group and resource, whether it needs an expiry (and the maximum lifetime in days, 0 for no maximum), which roles may grant it and whether its public routes are live (`enabled`). Requires a console session of an Owner or Manager; an API token is refused with 403.",
        "tags": [
          "API Tokens"
        ],
        "security": [
          {
            "consoleSession": []
          }
        ],
        "x-auth": "session",
        "x-required-roles": [
          "owner",
          "manager"
        ],
        "responses": {
          "200": {
            "description": "The catalogue, sorted by group and scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScopeCatalogResponse"
                },
                "examples": {
                  "catalogue": {
                    "$ref": "#/components/examples/ScopeCatalogue"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/TokensUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TokensForbidden"
          }
        }
      }
    },
    "/tokens/{tokenId}": {
      "delete": {
        "operationId": "revokeToken",
        "summary": "Revoke an API token",
        "description": "Revoke a token (not from a support session: SUPPORT_SESSION_NO_MINT). Requests with it fail from then on; the token stays in the list with `revokedAt` and `revokedBy` set. Requires a console session of an Owner or Manager.",
        "tags": [
          "API Tokens"
        ],
        "security": [
          {
            "consoleSession": []
          }
        ],
        "x-auth": "session",
        "x-required-roles": [
          "owner",
          "manager"
        ],
        "x-doc-slug": "tokens/revoke",
        "parameters": [
          {
            "$ref": "#/components/parameters/TokenId"
          }
        ],
        "responses": {
          "204": {
            "description": "Revoked. No body."
          },
          "401": {
            "$ref": "#/components/responses/TokensUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/TokensForbidden"
          },
          "404": {
            "$ref": "#/components/responses/TokensNotFound"
          },
          "500": {
            "$ref": "#/components/responses/TokensInternalError"
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "getHealth",
        "summary": "Check API health",
        "description": "Answers 200 with `data.status` set to `ok` while the API is running. Public: send no `Authorization` header. The response may carry further informational fields in `data`; ignore any you do not recognise. A check that gets no 200 within your timeout should treat the API as unavailable. Requests are limited per client IP address (sustained 5 per second, bursts of 20); poll every few seconds at most. Health checks are not written to the request log.",
        "tags": [
          "Health"
        ],
        "security": [],
        "x-auth": "public",
        "x-doc-slug": "health/check",
        "responses": {
          "200": {
            "description": "The API is running.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                },
                "examples": {
                  "healthy": {
                    "$ref": "#/components/examples/Healthy"
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/HealthRateLimited"
          }
        }
      }
    },
    "/access": {
      "get": {
        "description": "Requires the `access_review:read` scope.",
        "operationId": "accessInventoryList",
        "parameters": [
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for accessId.",
            "in": "query",
            "name": "sort[accessId]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for updatedAt.",
            "in": "query",
            "name": "sort[updatedAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter accessId (eq).",
            "in": "query",
            "name": "filter[accessId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter accessId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[accessId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter assetId (eq).",
            "in": "query",
            "name": "filter[assetId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter assetId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[assetId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter employeeId (eq).",
            "in": "query",
            "name": "filter[employeeId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter employeeId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[employeeId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter identityType (eq).",
            "in": "query",
            "name": "filter[identityType][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter identityType (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[identityType][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter isDormant (eq).",
            "in": "query",
            "name": "filter[isDormant][eq]",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Filter isPrivileged (eq).",
            "in": "query",
            "name": "filter[isPrivileged][eq]",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Filter roleLevel (eq).",
            "in": "query",
            "name": "filter[roleLevel][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter roleLevel (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[roleLevel][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (eq).",
            "in": "query",
            "name": "filter[status][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[status][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (gte).",
            "in": "query",
            "name": "filter[updatedAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (lt).",
            "in": "query",
            "name": "filter[updatedAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "accessId": "acc_1hk3p9x2m4qa",
                          "accountState": "UNKNOWN",
                          "assetCriticality": "HIGH",
                          "assetId": "ast_1hfz2k8w0c7d",
                          "assetName": "Google Workspace",
                          "dormantDays": 1,
                          "employeeId": "empl_1hgyun41rx48",
                          "firstObservedAt": "2026-03-04T09:12:00Z",
                          "identityType": "HUMAN",
                          "isDormant": false,
                          "isPrivileged": true,
                          "lastDetectedAt": "2026-10-12T02:00:00Z",
                          "lastUsedAt": "2026-10-11T16:41:00Z",
                          "lastVerifiedAt": "2026-09-30T10:05:00Z",
                          "revocationSource": "",
                          "revokedAt": null,
                          "riskFactors": [
                            "ADMIN_LEVEL_ACCESS"
                          ],
                          "riskScore": 42,
                          "roleConfidence": 0.97,
                          "roleLevel": "ADMIN",
                          "status": "ACTIVE",
                          "updatedAt": "2026-10-12T02:00:00Z"
                        },
                        {
                          "accessId": "acc_1hk3pa0v7n2e",
                          "accountState": "UNKNOWN",
                          "assetCriticality": "CRITICAL",
                          "assetId": "ast_1hfz2m3r9t5b",
                          "assetName": "GitHub",
                          "dormantDays": 53,
                          "employeeId": "empl_1hgyv08q3k2m",
                          "firstObservedAt": "2026-01-15T08:00:00Z",
                          "identityType": "HUMAN",
                          "isDormant": true,
                          "isPrivileged": false,
                          "lastDetectedAt": "2026-10-12T02:00:00Z",
                          "lastUsedAt": "2026-08-20T11:30:00Z",
                          "lastVerifiedAt": null,
                          "revocationSource": "",
                          "revokedAt": null,
                          "riskFactors": [
                            "TERMINATED_EMPLOYEE_ACCESS",
                            "DORMANT_ACCESS"
                          ],
                          "riskScore": 68,
                          "roleConfidence": 0.88,
                          "roleLevel": "VIEWER",
                          "status": "ACTIVE",
                          "updatedAt": "2026-10-12T02:00:00Z"
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 214
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/AccessTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "List the access inventory (one row per grant)",
        "tags": [
          "access"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-scope": "access_review:read",
        "x-route-id": "access.inventory.list",
        "x-since": "W1.5",
        "x-doc-slug": "access/list"
      }
    },
    "/assets": {
      "get": {
        "description": "Requires the `asset:read` scope.",
        "operationId": "assetList",
        "parameters": [
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for id.",
            "in": "query",
            "name": "sort[id]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for updatedAt.",
            "in": "query",
            "name": "sort[updatedAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter assetName (eq).",
            "in": "query",
            "name": "filter[assetName][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter assetName (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[assetName][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter createdAt (gte).",
            "in": "query",
            "name": "filter[createdAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter createdAt (lt).",
            "in": "query",
            "name": "filter[createdAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter criticality (eq).",
            "in": "query",
            "name": "filter[criticality][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter criticality (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[criticality][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter dataClassification (eq).",
            "in": "query",
            "name": "filter[dataClassification][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter dataClassification (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[dataClassification][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (eq).",
            "in": "query",
            "name": "filter[id][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[id][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter kind (eq).",
            "in": "query",
            "name": "filter[kind][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter kind (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[kind][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (gte).",
            "in": "query",
            "name": "filter[updatedAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (lt).",
            "in": "query",
            "name": "filter[updatedAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "assetName": "Google Workspace",
                          "createdAt": "2026-02-11T10:20:00Z",
                          "criticality": "HIGH",
                          "dataClassification": "CONFIDENTIAL",
                          "id": "ast_1hfz2k8w0c7d",
                          "kind": "SAAS",
                          "ownerId": "empl_1hgyun41rx48",
                          "supplierId": "sup_1hd8c2x7q0wn",
                          "updatedAt": "2026-09-28T14:03:00Z"
                        },
                        {
                          "assetName": "GitHub",
                          "createdAt": "2026-02-11T10:21:00Z",
                          "criticality": "CRITICAL",
                          "id": "ast_1hfz2m3r9t5b",
                          "kind": "SAAS",
                          "ownerId": "empl_1hgyv08q3k2m",
                          "updatedAt": "2026-10-02T08:47:00Z"
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 37
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/AssetTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "List assets",
        "tags": [
          "asset"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-scope": "asset:read",
        "x-route-id": "asset.list",
        "x-since": "W1.1",
        "x-doc-slug": "assets/list"
      }
    },
    "/audit-trail": {
      "get": {
        "description": "Requires the `audit_log:read` scope. Needs the `audit_trail` plan feature.",
        "operationId": "audittrailList",
        "parameters": [
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for createdAt.",
            "in": "query",
            "name": "sort[createdAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for id.",
            "in": "query",
            "name": "sort[id]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for seqNum.",
            "in": "query",
            "name": "sort[seqNum]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter action (eq).",
            "in": "query",
            "name": "filter[action][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter action (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[action][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter actorId (eq).",
            "in": "query",
            "name": "filter[actorId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter actorId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[actorId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter createdAt (gte).",
            "in": "query",
            "name": "filter[createdAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter createdAt (lt).",
            "in": "query",
            "name": "filter[createdAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter id (eq).",
            "in": "query",
            "name": "filter[id][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[id][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter seqNum (gte).",
            "in": "query",
            "name": "filter[seqNum][gte]",
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Filter seqNum (lt).",
            "in": "query",
            "name": "filter[seqNum][lt]",
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Filter subjectType (eq).",
            "in": "query",
            "name": "filter[subjectType][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter subjectType (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[subjectType][in]",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "action": {
                            "code": "employee.updated",
                            "group": "employee"
                          },
                          "actorId": "usr_1hgyq7m2k9xa",
                          "chainStatus": "verified",
                          "createdAt": "2026-10-12T09:15:22Z",
                          "id": "6707c3a91f4e2b0012ab34cd",
                          "seqNum": 10482,
                          "subjectId": "empl_1hgyun41rx48",
                          "subjectType": "employee"
                        },
                        {
                          "action": {
                            "code": "asset.created",
                            "group": "asset"
                          },
                          "actorId": "apitoken:tok_1hj4w2c8n6pz",
                          "chainStatus": "verified",
                          "createdAt": "2026-10-12T09:16:05Z",
                          "id": "6707c3b41f4e2b0012ab34d0",
                          "seqNum": 10483,
                          "subjectId": "ast_1hk40c2n8v3r",
                          "subjectType": "asset"
                        }
                      ],
                      "error": null,
                      "meta": {
                        "hasMore": true,
                        "limit": 2,
                        "nextCursor": "c2VxOjEwNDgz"
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/AuditEntryTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503AuditUnavailableBillingUnavailable"
          }
        },
        "summary": "List audit trail entries (ids, codes and chain fields only)",
        "tags": [
          "audittrail"
        ],
        "x-audit-read": true,
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-feature": "audit_trail",
        "x-required-scope": "audit_log:read",
        "x-route-id": "audittrail.list",
        "x-since": "W1.7",
        "x-doc-slug": "audit-trail/list"
      }
    },
    "/audit-trail/verify": {
      "get": {
        "description": "Requires the `audit_log:verify` scope. Needs the `audit_trail` plan feature.",
        "operationId": "audittrailVerify",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": {
                        "acceptedBreakCount": 1,
                        "acceptedBreaks": [
                          {
                            "acceptanceSeq": 7420,
                            "approvedAt": "2026-09-02T12:00:00Z",
                            "breakClass": "concurrent_append",
                            "exceptionId": "6702a1f01f4e2b0012ab1203",
                            "seqNum": 7311
                          }
                        ],
                        "breakCount": 0,
                        "breaks": [],
                        "breaksTruncated": false,
                        "brokenAt": null,
                        "chainedEntries": 10140,
                        "effectiveBoundarySeq": 7420,
                        "exceptionBoundarySeq": 7420,
                        "firstChainedSeq": 1,
                        "legacyEntries": 341,
                        "pendingEntries": 2,
                        "protocolV2Seq": 6200,
                        "scanComplete": true,
                        "seqGapCount": 0,
                        "seqGaps": [],
                        "totalEntries": 10483,
                        "valid": true,
                        "verifiedAt": "2026-10-13T07:30:00Z"
                      },
                      "error": null
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/VerifyTokenDTO"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    }
                  },
                  "required": [
                    "data",
                    "error"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400ValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "Verify the audit trail hash chain",
        "tags": [
          "audittrail"
        ],
        "x-cost": "heavy",
        "x-pii-class": "none",
        "x-required-feature": "audit_trail",
        "x-required-scope": "audit_log:verify",
        "x-route-id": "audittrail.verify",
        "x-since": "W1",
        "x-doc-slug": "audit-trail/verify"
      }
    },
    "/compliance/overview": {
      "get": {
        "description": "Requires the `compliance:read` scope. Needs the `compliance_overview` plan feature.",
        "operationId": "complianceOverviewGet",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": {
                        "dimensions": {
                          "evidenceFreshness": {
                            "fresh": 98,
                            "score": 82,
                            "stale": 22,
                            "total": 120
                          },
                          "gapCompliance": [
                            {
                              "compliant": 58,
                              "framework": "iso27001",
                              "missing": 15,
                              "na": 8,
                              "partial": 12,
                              "score": 71,
                              "totalControls": 93
                            }
                          ],
                          "riskExposure": {
                            "activeHigh": 3,
                            "activeMedium": 9,
                            "mitigated": 14,
                            "score": 68,
                            "totalRecords": 31
                          },
                          "supplierPosture": {
                            "agreementExpiring": 2,
                            "compliant": 17,
                            "criticalMissingAssessment": 1,
                            "reviewOverdue": 3,
                            "score": 77,
                            "totalSuppliers": 24
                          },
                          "vulnFindingPosture": {
                            "critical": 1,
                            "high": 7,
                            "low": 17,
                            "medium": 21,
                            "score": 70,
                            "totalOpen": 46
                          }
                        },
                        "generatedAt": "2026-10-13T06:00:00Z",
                        "overallScore": 74,
                        "trend": [
                          {
                            "date": "2026-10-11",
                            "score": 72
                          },
                          {
                            "date": "2026-10-12",
                            "score": 73
                          },
                          {
                            "date": "2026-10-13",
                            "score": 74
                          }
                        ]
                      },
                      "error": null
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/OverviewTokenDTO"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    }
                  },
                  "required": [
                    "data",
                    "error"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "Get the compliance posture overview (scores, counts, trend)",
        "tags": [
          "compliance"
        ],
        "x-cost": "heavy",
        "x-pii-class": "none",
        "x-required-feature": "compliance_overview",
        "x-required-scope": "compliance:read",
        "x-route-id": "compliance.overview.get",
        "x-since": "W1.4b",
        "x-doc-slug": "compliance/get-overview"
      }
    },
    "/compliance/states": {
      "get": {
        "description": "Requires the `compliance:read` scope. Needs the `continuous_monitoring` plan feature.",
        "operationId": "complianceStatesList",
        "parameters": [
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for stateId.",
            "in": "query",
            "name": "sort[stateId]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for updatedAt.",
            "in": "query",
            "name": "sort[updatedAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter objectiveId (eq).",
            "in": "query",
            "name": "filter[objectiveId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter objectiveId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[objectiveId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter state (eq).",
            "in": "query",
            "name": "filter[state][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter state (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[state][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter stateId (eq).",
            "in": "query",
            "name": "filter[stateId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter stateId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[stateId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (gte).",
            "in": "query",
            "name": "filter[updatedAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (lt).",
            "in": "query",
            "name": "filter[updatedAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "exceptionCount": 0,
                          "lastEvidenceAt": "2026-10-13T05:00:00Z",
                          "objectiveId": "obj_014",
                          "state": "healthy",
                          "stateId": "cst_1hk2z7r4m0qb",
                          "updatedAt": "2026-10-13T05:02:00Z"
                        },
                        {
                          "exceptionCount": 1,
                          "lastEvidenceAt": "2026-10-05T05:00:00Z",
                          "mttrMinutes": 240,
                          "objectiveId": "obj_027",
                          "state": "degraded",
                          "stateId": "cst_1hk2z8d1w6xn",
                          "updatedAt": "2026-10-12T05:02:00Z"
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 42
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/ControlStateTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "List control reliability states",
        "tags": [
          "compliance"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-feature": "continuous_monitoring",
        "x-required-scope": "compliance:read",
        "x-route-id": "compliance.states.list",
        "x-since": "W1.4b",
        "x-doc-slug": "compliance/list-states"
      }
    },
    "/employees": {
      "get": {
        "description": "Requires the `employee:read` scope. Identity fields are present only for tokens that also hold `pii:read`. With `pii:read`, a page holds at most 100 rows (a larger `limit` is VALIDATION_FAILED), a name search (`q`) runs in cursor mode only (no `offset`, no `total`), and each page or search is audited and spends one unit of the token's hourly personal-data budget per identity returned (at least one per search); a page that does not fit is RATE_LIMITED and spends nothing.",
        "operationId": "employeeList",
        "parameters": [
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for id.",
            "in": "query",
            "name": "sort[id]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for updatedAt.",
            "in": "query",
            "name": "sort[updatedAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter employmentType (eq).",
            "in": "query",
            "name": "filter[employmentType][eq]",
            "schema": {
              "enum": [
                "consultant",
                "contractor",
                "employee",
                "freelance",
                "full_time",
                "intern",
                "part_time",
                "seasonal",
                "temporary",
                "vendor"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter employmentType (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[employmentType][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (eq).",
            "in": "query",
            "name": "filter[id][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[id][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter managerId (eq).",
            "in": "query",
            "name": "filter[managerId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter managerId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[managerId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (eq).",
            "in": "query",
            "name": "filter[status][eq]",
            "schema": {
              "enum": [
                "ACTIVE",
                "ONBOARDING",
                "TERMINATED"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter status (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[status][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (gte).",
            "in": "query",
            "name": "filter[updatedAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (lt).",
            "in": "query",
            "name": "filter[updatedAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "employmentType": "full_time",
                          "hireDate": "2024-03-01T00:00:00Z",
                          "id": "empl_1hgyun41rx48",
                          "leaveDate": null,
                          "managerId": "empl_1hgyq2b7z5tc",
                          "status": "ACTIVE",
                          "updatedAt": "2026-09-15T08:30:00Z"
                        },
                        {
                          "employmentType": "contractor",
                          "hireDate": "2025-06-02T00:00:00Z",
                          "id": "empl_1hgyv08q3k2m",
                          "leaveDate": "2026-08-31T00:00:00Z",
                          "managerId": "empl_1hgyq2b7z5tc",
                          "status": "TERMINATED",
                          "updatedAt": "2026-09-01T07:10:00Z"
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 58
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/EmployeeTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspendedPiiUnavailable"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503AuditUnavailableBillingUnavailable"
          }
        },
        "summary": "List employees (identity with pii:read only)",
        "tags": [
          "employee"
        ],
        "x-cost": "light",
        "x-pii-class": "identity",
        "x-required-scope": "employee:read",
        "x-route-id": "employee.list",
        "x-since": "W1.6",
        "x-doc-slug": "employees/list"
      }
    },
    "/employees/{id}/access-history": {
      "get": {
        "description": "Requires the `employee:read` scope.",
        "operationId": "employeeAccessHistoryGet",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for eventId.",
            "in": "query",
            "name": "sort[eventId]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for occurredAt.",
            "in": "query",
            "name": "sort[occurredAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter assetId (eq).",
            "in": "query",
            "name": "filter[assetId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter assetId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[assetId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter eventId (eq).",
            "in": "query",
            "name": "filter[eventId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter eventId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[eventId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter eventType (eq).",
            "in": "query",
            "name": "filter[eventType][eq]",
            "schema": {
              "enum": [
                "DETECTED",
                "REVOKED",
                "VERIFIED"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter eventType (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[eventType][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter occurredAt (gte).",
            "in": "query",
            "name": "filter[occurredAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter occurredAt (lt).",
            "in": "query",
            "name": "filter[occurredAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "assetId": "ast_1hfz2m3r9t5b",
                          "employeeId": "empl_1hgyv08q3k2m",
                          "eventId": "ace_1hk1d4q8s2wv",
                          "eventType": "DETECTED",
                          "occurredAt": "2026-01-15T08:00:00Z"
                        },
                        {
                          "assetId": "ast_1hfz2m3r9t5b",
                          "employeeId": "empl_1hgyv08q3k2m",
                          "eventId": "ace_1hk3x0m5t7yc",
                          "eventType": "REVOKED",
                          "occurredAt": "2026-09-02T02:00:00Z"
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 2
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/AccessEventTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "404": {
            "$ref": "#/components/responses/Error404NotFound"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "List an employee's access events",
        "tags": [
          "employee"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-scope": "employee:read",
        "x-route-id": "employee.access_history.get",
        "x-since": "W1.6",
        "x-doc-slug": "employees/get-access-history"
      }
    },
    "/iso/projects": {
      "get": {
        "description": "Requires the `iso:read` scope. Needs the `iso27001` plan feature.",
        "operationId": "isoProjectsList",
        "parameters": [
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for id.",
            "in": "query",
            "name": "sort[id]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for updatedAt.",
            "in": "query",
            "name": "sort[updatedAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter id (eq).",
            "in": "query",
            "name": "filter[id][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[id][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (eq).",
            "in": "query",
            "name": "filter[status][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[status][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (gte).",
            "in": "query",
            "name": "filter[updatedAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (lt).",
            "in": "query",
            "name": "filter[updatedAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "createdAt": "2026-02-11T10:00:00Z",
                          "id": "iso_1hfa8m2c4x0p",
                          "readinessScore": 68,
                          "stage1Date": "2026-11-18T00:00:00Z",
                          "stage2Date": null,
                          "standard": "ISO27001:2022",
                          "status": "ACTIVE",
                          "targetCertDate": "2027-02-26T00:00:00Z",
                          "updatedAt": "2026-10-12T18:20:00Z"
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 1
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/ISOProjectTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "List ISO projects",
        "tags": [
          "iso"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-feature": "iso27001",
        "x-required-scope": "iso:read",
        "x-route-id": "iso.projects.list",
        "x-since": "W1.4a",
        "x-doc-slug": "iso-projects/list"
      }
    },
    "/iso/projects/{projectId}": {
      "get": {
        "description": "Requires the `iso:read` scope. Needs the `iso27001` plan feature.",
        "operationId": "isoProjectsGet",
        "parameters": [
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": {
                        "createdAt": "2026-02-11T10:00:00Z",
                        "id": "iso_1hfa8m2c4x0p",
                        "readinessScore": 68,
                        "stage1Date": "2026-11-18T00:00:00Z",
                        "stage2Date": null,
                        "standard": "ISO27001:2022",
                        "status": "ACTIVE",
                        "targetCertDate": "2027-02-26T00:00:00Z",
                        "updatedAt": "2026-10-12T18:20:00Z"
                      },
                      "error": null
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ISOProjectTokenDTO"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    }
                  },
                  "required": [
                    "data",
                    "error"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400ValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "404": {
            "$ref": "#/components/responses/Error404NotFound"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "Get one ISO project",
        "tags": [
          "iso"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-feature": "iso27001",
        "x-required-scope": "iso:read",
        "x-route-id": "iso.projects.get",
        "x-since": "W1.4a",
        "x-doc-slug": "iso-projects/get"
      }
    },
    "/iso/projects/{projectId}/evidence": {
      "get": {
        "description": "Requires the `evidence:read` scope. Needs the `iso27001` plan feature.",
        "operationId": "isoEvidenceList",
        "parameters": [
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for createdAt.",
            "in": "query",
            "name": "sort[createdAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for id.",
            "in": "query",
            "name": "sort[id]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter controlId (eq).",
            "in": "query",
            "name": "filter[controlId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter controlId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[controlId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter createdAt (gte).",
            "in": "query",
            "name": "filter[createdAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter createdAt (lt).",
            "in": "query",
            "name": "filter[createdAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter id (eq).",
            "in": "query",
            "name": "filter[id][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[id][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter sourceType (eq).",
            "in": "query",
            "name": "filter[sourceType][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter sourceType (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[sourceType][in]",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "collectedAt": "2026-10-13T04:00:00Z",
                          "controlId": "A.5.15",
                          "createdAt": "2026-10-13T04:00:03Z",
                          "id": "ev_1hk3m2b9r1xd",
                          "payloadType": "json",
                          "sourceType": "okta",
                          "stale": false
                        },
                        {
                          "collectedAt": "2026-06-30T12:00:00Z",
                          "controlId": "A.8.13",
                          "createdAt": "2026-06-30T12:04:00Z",
                          "id": "ev_1hj0w7c3k5qe",
                          "payloadType": "pdf",
                          "sourceType": "manual",
                          "stale": true
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 120
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/EvidenceTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "404": {
            "$ref": "#/components/responses/Error404NotFound"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "List a project's evidence metadata",
        "tags": [
          "iso"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-feature": "iso27001",
        "x-required-scope": "evidence:read",
        "x-route-id": "iso.evidence.list",
        "x-since": "W1.4a",
        "x-doc-slug": "iso-projects/list-evidence"
      }
    },
    "/iso/projects/{projectId}/gap": {
      "get": {
        "description": "Requires the `iso:read` scope. Needs the `iso27001` plan feature.",
        "operationId": "isoGapList",
        "parameters": [
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for controlId.",
            "in": "query",
            "name": "sort[controlId]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for updatedAt.",
            "in": "query",
            "name": "sort[updatedAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter controlId (eq).",
            "in": "query",
            "name": "filter[controlId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter controlId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[controlId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (eq).",
            "in": "query",
            "name": "filter[status][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[status][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (gte).",
            "in": "query",
            "name": "filter[updatedAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (lt).",
            "in": "query",
            "name": "filter[updatedAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "controlId": "A.5.1",
                          "gapCount": 0,
                          "isBlocking": false,
                          "lastAssessedAt": "2026-10-12T03:00:00Z",
                          "status": "COMPLIANT",
                          "updatedAt": "2026-10-12T03:00:00Z"
                        },
                        {
                          "controlId": "A.8.13",
                          "gapCount": 2,
                          "isBlocking": true,
                          "lastAssessedAt": "2026-10-12T03:00:00Z",
                          "status": "PARTIAL",
                          "updatedAt": "2026-10-12T03:00:00Z"
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 93
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/GapControlTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "404": {
            "$ref": "#/components/responses/Error404NotFound"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "List a project's gap controls",
        "tags": [
          "iso"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-feature": "iso27001",
        "x-required-scope": "iso:read",
        "x-route-id": "iso.gap.list",
        "x-since": "W1.4a",
        "x-doc-slug": "iso-projects/list-gap"
      }
    },
    "/iso/projects/{projectId}/monitoring": {
      "get": {
        "description": "Requires the `compliance:read` scope. Needs the `continuous_monitoring` plan feature.",
        "operationId": "monitorStatusGet",
        "parameters": [
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": {
                        "controls": [
                          {
                            "collectionEnabled": true,
                            "consecutiveFailures": 0,
                            "controlId": "A.5.15",
                            "freshness": "FRESH",
                            "lastRunAt": "2026-10-13T04:00:00Z",
                            "lastRunStatus": "COMPLETED"
                          },
                          {
                            "collectionEnabled": true,
                            "consecutiveFailures": 0,
                            "controlId": "A.8.13",
                            "freshness": "STALE",
                            "lastRunAt": "2026-10-06T04:00:00Z",
                            "lastRunStatus": "COMPLETED"
                          },
                          {
                            "collectionEnabled": true,
                            "consecutiveFailures": 3,
                            "controlId": "A.8.16",
                            "freshness": "FAILED",
                            "lastRunAt": "2026-10-13T04:00:00Z",
                            "lastRunStatus": "FAILED"
                          }
                        ],
                        "projectId": "iso_1hfa8m2c4x0p",
                        "summary": {
                          "failed": 1,
                          "fresh": 1,
                          "manualOnly": 0,
                          "stale": 1,
                          "total": 3
                        }
                      },
                      "error": null
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/MonitoringStatusTokenDTO"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    }
                  },
                  "required": [
                    "data",
                    "error"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400ValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "404": {
            "$ref": "#/components/responses/Error404NotFound"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "Get a project's continuous monitoring status",
        "tags": [
          "monitor"
        ],
        "x-cost": "heavy",
        "x-pii-class": "none",
        "x-required-feature": "continuous_monitoring",
        "x-required-scope": "compliance:read",
        "x-route-id": "monitor.status.get",
        "x-since": "W1.4b",
        "x-doc-slug": "iso-projects/get-monitoring"
      }
    },
    "/iso/projects/{projectId}/policies": {
      "get": {
        "description": "Requires the `iso:read` scope. Needs the `iso27001` plan feature.",
        "operationId": "isoPoliciesList",
        "parameters": [
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 50,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for id.",
            "in": "query",
            "name": "sort[id]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for updatedAt.",
            "in": "query",
            "name": "sort[updatedAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter id (eq).",
            "in": "query",
            "name": "filter[id][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[id][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter policyType (eq).",
            "in": "query",
            "name": "filter[policyType][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter policyType (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[policyType][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (eq).",
            "in": "query",
            "name": "filter[status][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[status][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (gte).",
            "in": "query",
            "name": "filter[updatedAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (lt).",
            "in": "query",
            "name": "filter[updatedAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "ackDone": 55,
                          "ackTotal": 58,
                          "id": "pol_1hfb0k3x9m2a",
                          "policyType": "INFO_SECURITY",
                          "publishedAt": "2026-07-01T09:00:00Z",
                          "status": "PUBLISHED",
                          "updatedAt": "2026-07-01T09:00:00Z",
                          "version": 3
                        },
                        {
                          "ackDone": 0,
                          "ackTotal": 0,
                          "id": "pol_1hfb0m7q2c4d",
                          "policyType": "ACCESS_CONTROL",
                          "publishedAt": null,
                          "status": "DRAFT",
                          "updatedAt": "2026-10-08T15:12:00Z",
                          "version": 1
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 8
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/PolicyTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "404": {
            "$ref": "#/components/responses/Error404NotFound"
          },
          "422": {
            "$ref": "#/components/responses/Error422QueryTooBroad"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "List a project's policies with acknowledgement counts",
        "tags": [
          "iso"
        ],
        "x-cost": "heavy",
        "x-pii-class": "none",
        "x-required-feature": "iso27001",
        "x-required-scope": "iso:read",
        "x-route-id": "iso.policies.list",
        "x-since": "W1.4a",
        "x-doc-slug": "iso-projects/list-policies"
      }
    },
    "/iso/projects/{projectId}/readiness": {
      "get": {
        "description": "Requires the `iso:read` scope. Needs the `iso27001` plan feature.",
        "operationId": "isoReadinessGet",
        "parameters": [
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": {
                        "blockers": [
                          {
                            "code": "CONTROL_MISSING_EVIDENCE",
                            "count": 15
                          },
                          {
                            "code": "SOA_NOT_SIGNED",
                            "count": 1
                          }
                        ],
                        "computedAt": "2026-10-13T07:30:00Z",
                        "projectId": "iso_1hfa8m2c4x0p",
                        "projectStatus": "ACTIVE",
                        "score": 68,
                        "warnings": [
                          {
                            "code": "CONTROL_EVIDENCE_STALE",
                            "count": 22
                          },
                          {
                            "code": "POLICY_ACK_RATE_LOW",
                            "count": 1
                          }
                        ]
                      },
                      "error": null
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/ReadinessTokenDTO"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    }
                  },
                  "required": [
                    "data",
                    "error"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400ValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "404": {
            "$ref": "#/components/responses/Error404NotFound"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "Get a project's audit readiness (codes and counts)",
        "tags": [
          "iso"
        ],
        "x-cost": "heavy",
        "x-pii-class": "none",
        "x-required-feature": "iso27001",
        "x-required-scope": "iso:read",
        "x-route-id": "iso.readiness.get",
        "x-since": "W1.4a",
        "x-doc-slug": "iso-projects/get-readiness"
      }
    },
    "/iso/projects/{projectId}/roadmap": {
      "get": {
        "description": "Requires the `iso:read` scope. Needs the `iso27001` plan feature.",
        "operationId": "isoRoadmapList",
        "parameters": [
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for id.",
            "in": "query",
            "name": "sort[id]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for updatedAt.",
            "in": "query",
            "name": "sort[updatedAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter controlId (eq).",
            "in": "query",
            "name": "filter[controlId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter controlId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[controlId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (eq).",
            "in": "query",
            "name": "filter[id][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[id][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter priority (eq).",
            "in": "query",
            "name": "filter[priority][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter priority (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[priority][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (eq).",
            "in": "query",
            "name": "filter[status][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[status][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (gte).",
            "in": "query",
            "name": "filter[updatedAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (lt).",
            "in": "query",
            "name": "filter[updatedAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "assignedToId": "empl_1hgyun41rx48",
                          "completedAt": null,
                          "controlId": "A.8.13",
                          "createdAt": "2026-09-20T10:00:00Z",
                          "dueAt": "2026-10-31T00:00:00Z",
                          "id": "task_1hk0p3c8v2xs",
                          "priority": "BLOCKING",
                          "status": "IN_PROGRESS",
                          "updatedAt": "2026-10-10T13:45:00Z"
                        },
                        {
                          "completedAt": "2026-09-26T16:20:00Z",
                          "controlId": "A.5.1",
                          "createdAt": "2026-09-20T10:00:00Z",
                          "dueAt": "2026-09-30T00:00:00Z",
                          "id": "task_1hk0p4f1n7qz",
                          "priority": "MEDIUM",
                          "status": "DONE",
                          "updatedAt": "2026-09-26T16:20:00Z"
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 27
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/RoadmapTaskTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "404": {
            "$ref": "#/components/responses/Error404NotFound"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "List a project's roadmap tasks",
        "tags": [
          "iso"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-feature": "iso27001",
        "x-required-scope": "iso:read",
        "x-route-id": "iso.roadmap.list",
        "x-since": "W1.4a",
        "x-doc-slug": "iso-projects/list-roadmap"
      }
    },
    "/iso/projects/{projectId}/soa": {
      "get": {
        "description": "Requires the `iso:read` scope. Needs the `iso27001` plan feature.",
        "operationId": "isoSoaList",
        "parameters": [
          {
            "in": "path",
            "name": "projectId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for controlId.",
            "in": "query",
            "name": "sort[controlId]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for updatedAt.",
            "in": "query",
            "name": "sort[updatedAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter applicable (eq).",
            "in": "query",
            "name": "filter[applicable][eq]",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Filter controlId (eq).",
            "in": "query",
            "name": "filter[controlId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter controlId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[controlId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter implementationStatus (eq).",
            "in": "query",
            "name": "filter[implementationStatus][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter implementationStatus (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[implementationStatus][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (gte).",
            "in": "query",
            "name": "filter[updatedAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (lt).",
            "in": "query",
            "name": "filter[updatedAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "aiFlag": false,
                          "applicable": true,
                          "controlId": "A.5.1",
                          "implementationStatus": "APPROVED",
                          "updatedAt": "2026-09-01T11:00:00Z"
                        },
                        {
                          "aiFlag": true,
                          "applicable": false,
                          "controlId": "A.7.4",
                          "implementationStatus": "REVIEW",
                          "updatedAt": "2026-10-03T09:30:00Z"
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 93
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/SoAEntryTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "404": {
            "$ref": "#/components/responses/Error404NotFound"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "List a project's Statement of Applicability entries",
        "tags": [
          "iso"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-feature": "iso27001",
        "x-required-scope": "iso:read",
        "x-route-id": "iso.soa.list",
        "x-since": "W1.4a",
        "x-doc-slug": "iso-projects/list-soa"
      }
    },
    "/risk/records": {
      "get": {
        "description": "Requires the `risk:read` scope. Needs the `risk_management` plan feature.",
        "operationId": "riskRecordsList",
        "parameters": [
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for id.",
            "in": "query",
            "name": "sort[id]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for updatedAt.",
            "in": "query",
            "name": "sort[updatedAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter domain (eq).",
            "in": "query",
            "name": "filter[domain][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter domain (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[domain][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (eq).",
            "in": "query",
            "name": "filter[id][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[id][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter ownerId (eq).",
            "in": "query",
            "name": "filter[ownerId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter ownerId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[ownerId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (eq).",
            "in": "query",
            "name": "filter[status][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[status][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter strategy (eq).",
            "in": "query",
            "name": "filter[strategy][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter strategy (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[strategy][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter supplierId (eq).",
            "in": "query",
            "name": "filter[supplierId][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter supplierId (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[supplierId][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (gte).",
            "in": "query",
            "name": "filter[updatedAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (lt).",
            "in": "query",
            "name": "filter[updatedAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "assetIds": [
                            "ast_1hfz2m3r9t5b"
                          ],
                          "businessOwnerId": "empl_1hgyq2b7z5tc",
                          "controlIds": [
                            "A.5.18",
                            "A.8.2"
                          ],
                          "createdAt": "2026-08-04T09:00:00Z",
                          "domain": "access",
                          "dueAt": "2026-12-31T00:00:00Z",
                          "id": "rrec_1hj7c2m8x4qa",
                          "inherentScore": 16,
                          "ownerId": "empl_1hgyq2b7z5tc",
                          "residualScore": 8,
                          "status": "active",
                          "strategy": "minimize",
                          "supplierId": "sup_1hd8c2x7q0wn",
                          "technicalOwnerId": "empl_1hgyun41rx48",
                          "updatedAt": "2026-10-09T14:10:00Z"
                        },
                        {
                          "assetIds": [],
                          "controlIds": [
                            "A.5.31"
                          ],
                          "createdAt": "2026-10-11T08:00:00Z",
                          "domain": "compliance",
                          "dueAt": null,
                          "id": "rrec_1hj7c5w0k2nd",
                          "inherentScore": null,
                          "residualScore": null,
                          "status": "awaiting_review",
                          "updatedAt": "2026-10-11T08:00:00Z"
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 31
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/RiskRecordTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "List risk records",
        "tags": [
          "risk"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-feature": "risk_management",
        "x-required-scope": "risk:read",
        "x-route-id": "risk.records.list",
        "x-since": "W1.2",
        "x-doc-slug": "risk-records/list"
      }
    },
    "/risk/records/{id}": {
      "get": {
        "description": "Requires the `risk:read` scope. Needs the `risk_management` plan feature.",
        "operationId": "riskRecordsGet",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": {
                        "assetIds": [
                          "ast_1hfz2m3r9t5b"
                        ],
                        "businessOwnerId": "empl_1hgyq2b7z5tc",
                        "controlIds": [
                          "A.5.18",
                          "A.8.2"
                        ],
                        "createdAt": "2026-08-04T09:00:00Z",
                        "domain": "access",
                        "dueAt": "2026-12-31T00:00:00Z",
                        "id": "rrec_1hj7c2m8x4qa",
                        "inherentScore": 16,
                        "ownerId": "empl_1hgyq2b7z5tc",
                        "residualScore": 8,
                        "status": "active",
                        "strategy": "minimize",
                        "supplierId": "sup_1hd8c2x7q0wn",
                        "technicalOwnerId": "empl_1hgyun41rx48",
                        "updatedAt": "2026-10-09T14:10:00Z"
                      },
                      "error": null
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/RiskRecordTokenDTO"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    }
                  },
                  "required": [
                    "data",
                    "error"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400ValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "404": {
            "$ref": "#/components/responses/Error404NotFound"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "Get one risk record",
        "tags": [
          "risk"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-feature": "risk_management",
        "x-required-scope": "risk:read",
        "x-route-id": "risk.records.get",
        "x-since": "W1.2",
        "x-doc-slug": "risk-records/get"
      }
    },
    "/suppliers": {
      "get": {
        "description": "Requires the `supplier:read` scope.",
        "operationId": "supplierList",
        "parameters": [
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for id.",
            "in": "query",
            "name": "sort[id]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for updatedAt.",
            "in": "query",
            "name": "sort[updatedAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter assessmentStatus (eq).",
            "in": "query",
            "name": "filter[assessmentStatus][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter assessmentStatus (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[assessmentStatus][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter criticality (eq).",
            "in": "query",
            "name": "filter[criticality][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter criticality (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[criticality][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (eq).",
            "in": "query",
            "name": "filter[id][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[id][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter serviceCategory (eq).",
            "in": "query",
            "name": "filter[serviceCategory][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter serviceCategory (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[serviceCategory][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (eq).",
            "in": "query",
            "name": "filter[status][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[status][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (gte).",
            "in": "query",
            "name": "filter[updatedAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (lt).",
            "in": "query",
            "name": "filter[updatedAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "assessmentStatus": "completed",
                          "businessOwnerId": "empl_1hgyq2b7z5tc",
                          "createdAt": "2026-02-12T09:00:00Z",
                          "criticality": "CRITICAL",
                          "dependencyType": "single",
                          "displayName": "Example Cloud",
                          "hasCardData": false,
                          "hasPhi": false,
                          "hasPii": true,
                          "id": "sup_1hd8c2x7q0wn",
                          "lastAssessmentAt": "2026-05-20T10:00:00Z",
                          "legalName": "Example Cloud Services Ltd.",
                          "networkAccessLevel": "privileged",
                          "nextAssessmentDueAt": "2027-05-20T00:00:00Z",
                          "openFindingCount": 3,
                          "openRiskCount": 2,
                          "privilegedAccess": true,
                          "securityOwnerId": "empl_1hgyun41rx48",
                          "serviceCategory": "Cloud Provider",
                          "status": "active",
                          "supplierOwnerId": "empl_1hgyun41rx48",
                          "supportsCrownJewel": true,
                          "updatedAt": "2026-10-01T12:00:00Z"
                        },
                        {
                          "assessmentStatus": "not_started",
                          "createdAt": "2026-10-07T13:00:00Z",
                          "criticality": "MEDIUM",
                          "displayName": "Example Payroll",
                          "hasCardData": false,
                          "hasPhi": false,
                          "hasPii": true,
                          "id": "sup_1hd8c4m1r9ty",
                          "legalName": "Example Payroll GmbH",
                          "networkAccessLevel": "none",
                          "openFindingCount": 0,
                          "openRiskCount": 0,
                          "privilegedAccess": false,
                          "serviceCategory": "Payroll",
                          "status": "onboarding",
                          "supportsCrownJewel": false,
                          "updatedAt": "2026-10-07T13:00:00Z"
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 24
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/SupplierTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "List suppliers",
        "tags": [
          "supplier"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-scope": "supplier:read",
        "x-route-id": "supplier.list",
        "x-since": "W1.3",
        "x-doc-slug": "suppliers/list"
      }
    },
    "/suppliers/{supplierId}": {
      "get": {
        "description": "Requires the `supplier:read` scope.",
        "operationId": "supplierGet",
        "parameters": [
          {
            "in": "path",
            "name": "supplierId",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": {
                        "assessmentStatus": "completed",
                        "businessOwnerId": "empl_1hgyq2b7z5tc",
                        "createdAt": "2026-02-12T09:00:00Z",
                        "criticality": "CRITICAL",
                        "dependencyType": "single",
                        "displayName": "Example Cloud",
                        "hasCardData": false,
                        "hasPhi": false,
                        "hasPii": true,
                        "id": "sup_1hd8c2x7q0wn",
                        "lastAssessmentAt": "2026-05-20T10:00:00Z",
                        "legalName": "Example Cloud Services Ltd.",
                        "networkAccessLevel": "privileged",
                        "nextAssessmentDueAt": "2027-05-20T00:00:00Z",
                        "openFindingCount": 3,
                        "openRiskCount": 2,
                        "privilegedAccess": true,
                        "securityOwnerId": "empl_1hgyun41rx48",
                        "serviceCategory": "Cloud Provider",
                        "status": "active",
                        "supplierOwnerId": "empl_1hgyun41rx48",
                        "supportsCrownJewel": true,
                        "updatedAt": "2026-10-01T12:00:00Z"
                      },
                      "error": null
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/SupplierTokenDTO"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    }
                  },
                  "required": [
                    "data",
                    "error"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400ValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "404": {
            "$ref": "#/components/responses/Error404NotFound"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "Get one supplier",
        "tags": [
          "supplier"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-scope": "supplier:read",
        "x-route-id": "supplier.get",
        "x-since": "W0.11",
        "x-doc-slug": "suppliers/get"
      }
    },
    "/suppliers/{supplierId}/agreements": {
      "get": {
        "description": "Requires the `supplier:read` scope.",
        "operationId": "supplierAgreementsList",
        "parameters": [
          {
            "in": "path",
            "name": "supplierId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for id.",
            "in": "query",
            "name": "sort[id]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for updatedAt.",
            "in": "query",
            "name": "sort[updatedAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter contractEnd (gte).",
            "in": "query",
            "name": "filter[contractEnd][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter contractEnd (lt).",
            "in": "query",
            "name": "filter[contractEnd][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter id (eq).",
            "in": "query",
            "name": "filter[id][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[id][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (gte).",
            "in": "query",
            "name": "filter[updatedAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (lt).",
            "in": "query",
            "name": "filter[updatedAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "breachNoticeHours": 48,
                          "contractEnd": "2027-05-31T00:00:00Z",
                          "contractStart": "2025-06-01T00:00:00Z",
                          "createdAt": "2026-02-12T09:30:00Z",
                          "dataDeletionTimelineDays": 30,
                          "dpaSigned": true,
                          "id": "sagr_1hd9a0x3m7qp",
                          "rightToAudit": true,
                          "sccsVersion": "2021-c2p",
                          "securityAddendumSigned": true,
                          "supplierId": "sup_1hd8c2x7q0wn",
                          "transferImpactAssessmentRequired": true,
                          "updatedAt": "2026-06-03T10:00:00Z"
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 1
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/AgreementTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "404": {
            "$ref": "#/components/responses/Error404NotFound"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "List a supplier's agreements",
        "tags": [
          "supplier"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-scope": "supplier:read",
        "x-route-id": "supplier.agreements.list",
        "x-since": "W1.3",
        "x-doc-slug": "suppliers/list-agreements"
      }
    },
    "/suppliers/{supplierId}/assessments": {
      "get": {
        "description": "Requires the `supplier:read` scope.",
        "operationId": "supplierAssessmentsList",
        "parameters": [
          {
            "in": "path",
            "name": "supplierId",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Page size.",
            "in": "query",
            "name": "limit",
            "schema": {
              "default": 25,
              "maximum": 100,
              "minimum": 1,
              "type": "integer"
            }
          },
          {
            "description": "Rows to skip (offset mode). Cannot be combined with cursor.",
            "in": "query",
            "name": "offset",
            "schema": {
              "default": 0,
              "maximum": 10000,
              "minimum": 0,
              "type": "integer"
            }
          },
          {
            "description": "An opaque cursor taken from meta.nextCursor of the previous page (cursor mode). Valid for 24 hours and bound to the token and the query; do not parse or construct it.",
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sort direction for id.",
            "in": "query",
            "name": "sort[id]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Sort direction for updatedAt.",
            "in": "query",
            "name": "sort[updatedAt]",
            "schema": {
              "enum": [
                "asc",
                "desc"
              ],
              "type": "string"
            }
          },
          {
            "description": "Filter id (eq).",
            "in": "query",
            "name": "filter[id][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter id (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[id][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (eq).",
            "in": "query",
            "name": "filter[status][eq]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter status (in). Comma-separated, at most 50 values.",
            "in": "query",
            "name": "filter[status][in]",
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (gte).",
            "in": "query",
            "name": "filter[updatedAt][gte]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          },
          {
            "description": "Filter updatedAt (lt).",
            "in": "query",
            "name": "filter[updatedAt][lt]",
            "schema": {
              "format": "date-time",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "createdAt": "2026-04-28T08:55:00Z",
                          "dueAt": "2027-05-20T00:00:00Z",
                          "id": "sasm_1hfx2c7k0m4w",
                          "mode": "full",
                          "overallRiskRating": "medium",
                          "reviewedAt": "2026-05-20T10:00:00Z",
                          "riskRating": "medium",
                          "score": 81,
                          "sentAt": "2026-04-28T09:00:00Z",
                          "status": "completed",
                          "submittedAt": "2026-05-12T15:30:00Z",
                          "supplierId": "sup_1hd8c2x7q0wn",
                          "updatedAt": "2026-05-20T10:00:00Z"
                        }
                      ],
                      "error": null,
                      "meta": {
                        "limit": 25,
                        "offset": 0,
                        "total": 1
                      }
                    }
                  }
                },
                "schema": {
                  "additionalProperties": false,
                  "properties": {
                    "data": {
                      "items": {
                        "$ref": "#/components/schemas/AssessmentTokenDTO"
                      },
                      "type": "array"
                    },
                    "error": {
                      "additionalProperties": false,
                      "description": "Always null on success.",
                      "nullable": true,
                      "type": "object"
                    },
                    "meta": {
                      "description": "Offset mode (the request sends the offset parameter) returns total, limit and offset. Otherwise the list is in cursor mode and returns limit, hasMore and nextCursor; nextCursor is null on the last page.",
                      "oneOf": [
                        {
                          "$ref": "#/components/schemas/OffsetMeta"
                        },
                        {
                          "$ref": "#/components/schemas/CursorMeta"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "error",
                    "meta"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimit-Limit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimit-Remaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimit-Reset"
              },
              "X-Request-ID": {
                "$ref": "#/components/headers/X-Request-ID"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400InvalidCursorValidationFailed"
          },
          "401": {
            "$ref": "#/components/responses/Error401InvalidTokenUnauthorized"
          },
          "402": {
            "$ref": "#/components/responses/Error402FeatureGated"
          },
          "403": {
            "$ref": "#/components/responses/Error403ForbiddenInsufficientScopeOrgSuspended"
          },
          "404": {
            "$ref": "#/components/responses/Error404NotFound"
          },
          "429": {
            "$ref": "#/components/responses/Error429RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/Error500InternalError"
          },
          "503": {
            "$ref": "#/components/responses/Error503BillingUnavailable"
          }
        },
        "summary": "List a supplier's assessments",
        "tags": [
          "supplier"
        ],
        "x-cost": "light",
        "x-pii-class": "none",
        "x-required-scope": "supplier:read",
        "x-route-id": "supplier.assessments.list",
        "x-since": "W1.3",
        "x-doc-slug": "suppliers/list-assessments"
      }
    }
  },
  "components": {
    "schemas": {
      "Summary": {
        "type": "object",
        "description": "Counts of leaver items per reconciled status. total is the sum of the four.",
        "required": [
          "total",
          "revoked",
          "outstanding",
          "discrepancy",
          "attested"
        ],
        "properties": {
          "total": {
            "type": "integer",
            "minimum": 0
          },
          "revoked": {
            "type": "integer",
            "minimum": 0
          },
          "outstanding": {
            "type": "integer",
            "minimum": 0
          },
          "discrepancy": {
            "type": "integer",
            "minimum": 0
          },
          "attested": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "Employee": {
        "type": "object",
        "description": "Identity block of a case. Only employeeId is guaranteed; the other fields are absent when unknown or not disclosed.",
        "required": [
          "employeeId"
        ],
        "properties": {
          "employeeId": {
            "type": "string",
            "description": "Internal employee id."
          },
          "emailMasked": {
            "type": "string",
            "description": "Masked email address, safe to display."
          },
          "name": {
            "type": "string",
            "description": "Full name. Present only for tokens holding both jml:read and pii:read; without pii:read the key is absent."
          },
          "email": {
            "type": "string",
            "description": "Email address. Present only for tokens holding both jml:read and pii:read; without pii:read the key is absent."
          },
          "department": {
            "type": "string"
          },
          "jobTitle": {
            "type": "string"
          },
          "employmentType": {
            "type": "string"
          },
          "employeeStatus": {
            "type": "string"
          },
          "startDate": {
            "type": "string",
            "format": "date",
            "description": "Calendar date YYYY-MM-DD."
          },
          "endDate": {
            "type": "string",
            "format": "date",
            "description": "Calendar date YYYY-MM-DD."
          }
        }
      },
      "Case": {
        "type": "object",
        "required": [
          "caseId",
          "employee",
          "status",
          "openedAt",
          "dueAt",
          "summary",
          "clean"
        ],
        "properties": {
          "caseId": {
            "type": "string",
            "example": "lfc_example000001"
          },
          "employee": {
            "$ref": "#/components/schemas/Employee"
          },
          "status": {
            "type": "string",
            "enum": [
              "OPEN",
              "IN_PROGRESS",
              "COMPLETED",
              "CANCELLED"
            ],
            "description": "Case status, returned as stored; it is not derived from the item statuses. A COMPLETED case that still shows a DISCREPANCY is exactly the signal this API exists for."
          },
          "openedAt": {
            "type": "string",
            "format": "date-time"
          },
          "dueAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "summary": {
            "$ref": "#/components/schemas/Summary"
          },
          "clean": {
            "type": "boolean",
            "description": "True when no item is outstanding or in discrepancy."
          }
        }
      },
      "Item": {
        "type": "object",
        "required": [
          "itemId",
          "itemKey",
          "taskId",
          "caseId",
          "employeeId",
          "assetId",
          "assetName",
          "status",
          "taskStatus",
          "accessStatus",
          "source",
          "openedAt",
          "taskCompletedAt",
          "accessLastDetectedAt"
        ],
        "properties": {
          "itemId": {
            "type": "string"
          },
          "itemKey": {
            "type": "string",
            "description": "Stable key for deduplicating items across polls: caseId:assetId for an item tied to an application, caseId:taskId for a manual step. It does not change if the asset is later deleted."
          },
          "taskId": {
            "type": "string",
            "nullable": true,
            "description": "Null for ACCESS_ONLY items."
          },
          "caseId": {
            "type": "string"
          },
          "employeeId": {
            "type": "string"
          },
          "assetId": {
            "type": "string",
            "nullable": true,
            "description": "Null for MANUAL_TASK items. Older assets may carry a 24-character hex asset id."
          },
          "assetName": {
            "type": "string",
            "nullable": true,
            "description": "Null when the asset no longer exists or the item is manual."
          },
          "status": {
            "type": "string",
            "enum": [
              "REVOKED",
              "OUTSTANDING",
              "DISCREPANCY",
              "ATTESTED"
            ],
            "description": "Reconciled each time you read it, from the task status and the access inventory.\nREVOKED: the inventory shows the access is gone (a stale pending task can still be present; taskStatus tells you); nothing to do.\nOUTSTANDING: the access is still active and nobody has marked it done, or it is a manual step that is not done; also used for access detected after the case was opened. Remove the access, then wait for the next access scan.\nDISCREPANCY: someone marked the task done but the access is still detected (a failed removal, a re-provisioned account or stale data). Check it first.\nATTESTED: a person marked the item done in the console and the access is not detected; neither verified nor contradicted.\n"
          },
          "taskStatus": {
            "type": "string",
            "nullable": true,
            "description": "Null for ACCESS_ONLY items."
          },
          "accessStatus": {
            "type": "string",
            "nullable": true,
            "description": "Null when no access record exists."
          },
          "source": {
            "type": "string",
            "enum": [
              "TASK",
              "ACCESS_ONLY",
              "MANUAL_TASK"
            ],
            "description": "TASK: a task on the case. ACCESS_ONLY: access detected with no task; it is attached to the leaver's most recent case. MANUAL_TASK: a step that is not tied to an application."
          },
          "openedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Opening time of the owning case."
          },
          "taskCompletedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When a person marked the task done. There is no \"revoked at\" field, because access detection time is not a scan time; use this field."
          },
          "accessLastDetectedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "ListMeta": {
        "type": "object",
        "required": [
          "limit",
          "offset",
          "total",
          "accessDataAsOf"
        ],
        "properties": {
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "accessDataAsOf": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Latest access detection time used for this response."
          }
        }
      },
      "CaseMeta": {
        "type": "object",
        "required": [
          "accessDataAsOf"
        ],
        "properties": {
          "accessDataAsOf": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Latest access detection time used for this response."
          }
        }
      },
      "ItemListMeta": {
        "type": "object",
        "required": [
          "limit",
          "offset",
          "total",
          "summary",
          "accessDataAsOf"
        ],
        "properties": {
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "summary": {
            "$ref": "#/components/schemas/Summary"
          },
          "accessDataAsOf": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Latest access detection time used for this response."
          }
        }
      },
      "CaseListResponse": {
        "type": "object",
        "required": [
          "data",
          "error",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Case"
            }
          },
          "error": {
            "type": "object",
            "nullable": true,
            "description": "Always null on success."
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      },
      "CaseResponse": {
        "type": "object",
        "required": [
          "data",
          "error",
          "meta"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Case"
          },
          "error": {
            "type": "object",
            "nullable": true,
            "description": "Always null on success."
          },
          "meta": {
            "$ref": "#/components/schemas/CaseMeta"
          }
        }
      },
      "ItemListResponse": {
        "type": "object",
        "required": [
          "data",
          "error",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Item"
            }
          },
          "error": {
            "type": "object",
            "nullable": true,
            "description": "Always null on success."
          },
          "meta": {
            "$ref": "#/components/schemas/ItemListMeta"
          }
        }
      },
      "OnboardingSummary": {
        "type": "object",
        "description": "Counts of joiner items per reconciled status. total is the sum of the three.",
        "required": [
          "total",
          "granted",
          "pending",
          "attested"
        ],
        "properties": {
          "total": {
            "type": "integer",
            "minimum": 0
          },
          "granted": {
            "type": "integer",
            "minimum": 0
          },
          "pending": {
            "type": "integer",
            "minimum": 0
          },
          "attested": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "OnboardingCase": {
        "type": "object",
        "required": [
          "caseId",
          "employee",
          "status",
          "openedAt",
          "dueAt",
          "summary",
          "ready",
          "overdue",
          "generatedAt",
          "generatedFromProfileIds"
        ],
        "properties": {
          "caseId": {
            "type": "string",
            "example": "lfc_example000002"
          },
          "employee": {
            "$ref": "#/components/schemas/Employee"
          },
          "status": {
            "type": "string",
            "enum": [
              "OPEN",
              "IN_PROGRESS",
              "COMPLETED",
              "CANCELLED"
            ],
            "description": "Case status, returned as stored; it is not derived from the item statuses. Use ready and overdue for the reconciled picture."
          },
          "openedAt": {
            "type": "string",
            "format": "date-time"
          },
          "dueAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "summary": {
            "$ref": "#/components/schemas/OnboardingSummary"
          },
          "ready": {
            "type": "boolean",
            "description": "True when no item is pending (every item is granted or attested)."
          },
          "overdue": {
            "type": "boolean",
            "description": "True when an open case that is not ready is past its due date."
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When the items were generated from access profiles; null for cases created otherwise."
          },
          "generatedFromProfileIds": {
            "type": "array",
            "description": "Ids of the access profiles the items were generated from (ids only). Empty, never null.",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "OnboardingItem": {
        "type": "object",
        "required": [
          "itemId",
          "itemKey",
          "taskId",
          "caseId",
          "employeeId",
          "assetId",
          "assetName",
          "status",
          "accessStatus",
          "accessLastDetectedAt",
          "sourceProfileIds",
          "attestedAt",
          "source",
          "openedAt",
          "dueAt"
        ],
        "properties": {
          "itemId": {
            "type": "string"
          },
          "itemKey": {
            "type": "string",
            "description": "Stable key for deduplicating items across polls: caseId:assetId, or caseId:taskId for a manual task."
          },
          "taskId": {
            "type": "string",
            "nullable": true
          },
          "caseId": {
            "type": "string"
          },
          "employeeId": {
            "type": "string"
          },
          "assetId": {
            "type": "string",
            "nullable": true,
            "description": "Null for MANUAL_TASK items. Older assets may carry a 24-character hex asset id."
          },
          "assetName": {
            "type": "string",
            "nullable": true,
            "description": "Current name of the application; the name at generation when the application no longer exists; null for manual items."
          },
          "status": {
            "type": "string",
            "enum": [
              "GRANTED",
              "PENDING",
              "ATTESTED"
            ],
            "description": "Reconciled each time you read it, so an item turns GRANTED as soon as the access is detected, with no change to the case.\nGRANTED: the access inventory shows the access; nothing to do.\nPENDING: no access is detected and nobody has marked it done; give the access, then wait for the next access scan.\nATTESTED: a person marked it done in the console (shown as Marked done) but the access is not yet detected; neither verified nor contradicted. Verify if it matters.\n"
          },
          "accessStatus": {
            "type": "string",
            "nullable": true,
            "description": "Null when no access record exists."
          },
          "accessLastDetectedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "sourceProfileIds": {
            "type": "array",
            "description": "Ids of the access profiles that required the application (ids only). Empty, never null.",
            "items": {
              "type": "string"
            }
          },
          "attestedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "When a person marked the item done in the console. Null when nobody has."
          },
          "source": {
            "type": "string",
            "enum": [
              "PROFILE",
              "MANUAL_TASK"
            ]
          },
          "openedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Opening time of the owning case."
          },
          "dueAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Due date of the owning case."
          }
        }
      },
      "OnboardingItemListMeta": {
        "type": "object",
        "required": [
          "limit",
          "offset",
          "total",
          "summary",
          "accessDataAsOf"
        ],
        "properties": {
          "limit": {
            "type": "integer"
          },
          "offset": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "summary": {
            "$ref": "#/components/schemas/OnboardingSummary"
          },
          "accessDataAsOf": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Latest access detection time used for this response."
          }
        }
      },
      "OnboardingCaseListResponse": {
        "type": "object",
        "required": [
          "data",
          "error",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnboardingCase"
            }
          },
          "error": {
            "type": "object",
            "nullable": true,
            "description": "Always null on success."
          },
          "meta": {
            "$ref": "#/components/schemas/ListMeta"
          }
        }
      },
      "OnboardingCaseResponse": {
        "type": "object",
        "required": [
          "data",
          "error",
          "meta"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/OnboardingCase"
          },
          "error": {
            "type": "object",
            "nullable": true,
            "description": "Always null on success."
          },
          "meta": {
            "$ref": "#/components/schemas/CaseMeta"
          }
        }
      },
      "OnboardingItemListResponse": {
        "type": "object",
        "required": [
          "data",
          "error",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OnboardingItem"
            }
          },
          "error": {
            "type": "object",
            "nullable": true,
            "description": "Always null on success."
          },
          "meta": {
            "$ref": "#/components/schemas/OnboardingItemListMeta"
          }
        }
      },
      "ErrorEnvelope": {
        "type": "object",
        "description": "Error body. meta is optional and absent on some errors (for example 429).",
        "required": [
          "data",
          "error"
        ],
        "properties": {
          "data": {
            "type": "object",
            "nullable": true,
            "description": "Always null."
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "id": {
                "type": "string",
                "description": "Correlation id to quote to support."
              },
              "code": {
                "type": "string",
                "enum": [
                  "VALIDATION_FAILED",
                  "UNAUTHORIZED",
                  "INVALID_TOKEN",
                  "FORBIDDEN",
                  "INSUFFICIENT_SCOPE",
                  "FEATURE_GATED",
                  "NOT_FOUND",
                  "QUERY_TOO_BROAD",
                  "RATE_LIMITED",
                  "INTERNAL_ERROR",
                  "BILLING_UNAVAILABLE",
                  "AUDIT_UNAVAILABLE"
                ]
              },
              "message": {
                "type": "string",
                "description": "User-safe message."
              },
              "args": {
                "type": "object",
                "additionalProperties": true,
                "description": "Structured details such as the rejected parameter."
              }
            }
          },
          "meta": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "Sbom": {
        "type": "object",
        "required": [
          "orgId",
          "name",
          "source",
          "componentCount",
          "findingsCritical",
          "findingsHigh",
          "findingsMedium",
          "findingsLow",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "sbomId": {
            "type": "string"
          },
          "orgId": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "description": "Product or repository name."
          },
          "version": {
            "type": "string"
          },
          "assetId": {
            "type": "string",
            "description": "Linked asset id, when the SBOM belongs to a known asset."
          },
          "source": {
            "type": "string",
            "description": "How the SBOM was ingested.",
            "enum": [
              "go.sum",
              "pom.xml",
              "build.gradle",
              "package.json",
              "requirements.txt",
              "csproj",
              "Cargo.lock",
              "Gemfile.lock",
              "composer.lock",
              "Podfile.lock",
              "Package.resolved",
              "pubspec.lock",
              "cyclonedx",
              "spdx",
              "manual"
            ]
          },
          "sourceRef": {
            "type": "string",
            "description": "Git SHA, CI build id or filename."
          },
          "repoUrl": {
            "type": "string"
          },
          "branch": {
            "type": "string"
          },
          "commitSha": {
            "type": "string"
          },
          "componentCount": {
            "type": "integer",
            "minimum": 0
          },
          "findingsCritical": {
            "type": "integer",
            "minimum": 0
          },
          "findingsHigh": {
            "type": "integer",
            "minimum": 0
          },
          "findingsMedium": {
            "type": "integer",
            "minimum": 0
          },
          "findingsLow": {
            "type": "integer",
            "minimum": 0
          },
          "lastMatchedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Time of the last CVE matching run; absent before the first run."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SbomComponent": {
        "type": "object",
        "required": [
          "orgId",
          "sbomId",
          "name",
          "version",
          "ecosystem",
          "direct",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "componentId": {
            "type": "string"
          },
          "orgId": {
            "type": "string"
          },
          "sbomId": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "description": "Package name as used in its ecosystem."
          },
          "version": {
            "type": "string"
          },
          "ecosystem": {
            "type": "string",
            "enum": [
              "go",
              "maven",
              "npm",
              "pypi",
              "nuget",
              "cargo",
              "gem",
              "composer",
              "cocoapods",
              "swift",
              "pub",
              "hex",
              "rpm",
              "deb",
              "other"
            ]
          },
          "purl": {
            "type": "string",
            "description": "Package URL used for CVE matching."
          },
          "cpeUri": {
            "type": "string"
          },
          "upstreamName": {
            "type": "string",
            "description": "Canonical upstream project name used in CVE descriptions."
          },
          "direct": {
            "type": "boolean",
            "description": "True for a direct dependency, false for a transitive one."
          },
          "vendorId": {
            "type": "string",
            "description": "Linked vendor id, when the component comes from a tracked vendor."
          },
          "license": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "VulnFinding": {
        "type": "object",
        "required": [
          "orgId",
          "sbomId",
          "componentId",
          "cveId",
          "cveSource",
          "matchMethod",
          "confidence",
          "severity",
          "status",
          "slaBreach",
          "firstSeenAt",
          "updatedAt"
        ],
        "properties": {
          "findingId": {
            "type": "string"
          },
          "orgId": {
            "type": "string"
          },
          "sbomId": {
            "type": "string"
          },
          "componentId": {
            "type": "string"
          },
          "cveId": {
            "type": "string",
            "example": "CVE-2024-00000"
          },
          "cveSource": {
            "type": "string",
            "enum": [
              "nvd",
              "redhat"
            ]
          },
          "matchMethod": {
            "type": "string",
            "enum": [
              "cpe_exact",
              "cpe_version_range",
              "purl_exact",
              "purl_version_range",
              "rhsa_package",
              "manual"
            ]
          },
          "confidence": {
            "type": "string",
            "enum": [
              "high",
              "medium",
              "low"
            ]
          },
          "matchedVia": {
            "type": "string",
            "description": "Identifier the match was made on."
          },
          "severity": {
            "type": "string",
            "enum": [
              "CRITICAL",
              "HIGH",
              "MEDIUM",
              "LOW",
              "NONE"
            ]
          },
          "severityOverride": {
            "type": "string",
            "enum": [
              "CRITICAL",
              "HIGH",
              "MEDIUM",
              "LOW",
              "NONE"
            ],
            "description": "Present only when the severity was overridden."
          },
          "cvssV3Score": {
            "type": "number"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "mitigated",
              "accepted_risk",
              "false_positive",
              "fixed"
            ]
          },
          "assignedTo": {
            "type": "string"
          },
          "dueAt": {
            "type": "string",
            "format": "date-time"
          },
          "slaBreach": {
            "type": "boolean"
          },
          "fixedVersion": {
            "type": "string"
          },
          "remediationNotes": {
            "type": "string"
          },
          "vendorId": {
            "type": "string",
            "description": "Linked vendor id, when the vulnerable component comes from a tracked vendor."
          },
          "rhsaIds": {
            "type": "array",
            "description": "Red Hat advisories that provide the fix.",
            "items": {
              "type": "string"
            }
          },
          "firstSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "resolvedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SoftwareVendor": {
        "type": "object",
        "required": [
          "orgId",
          "name",
          "type",
          "riskTier",
          "assessmentStatus",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "vendorId": {
            "type": "string"
          },
          "orgId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "website": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "oss",
              "commercial",
              "internal"
            ]
          },
          "riskTier": {
            "type": "integer",
            "enum": [
              1,
              2,
              3
            ],
            "description": "1 is the highest risk."
          },
          "assessmentStatus": {
            "type": "string",
            "enum": [
              "not_started",
              "in_progress",
              "completed"
            ]
          },
          "lastAssessedAt": {
            "type": "string",
            "format": "date-time"
          },
          "notes": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "SeveritySummary": {
        "type": "object",
        "description": "Counts of open findings per severity.",
        "required": [
          "critical",
          "high",
          "medium",
          "low"
        ],
        "properties": {
          "critical": {
            "type": "integer",
            "minimum": 0
          },
          "high": {
            "type": "integer",
            "minimum": 0
          },
          "medium": {
            "type": "integer",
            "minimum": 0
          },
          "low": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "VendorRiskSummary": {
        "type": "object",
        "description": "Open findings of one vendor. total is the sum of the four severities.",
        "required": [
          "vendorId",
          "critical",
          "high",
          "medium",
          "low",
          "total"
        ],
        "properties": {
          "vendorId": {
            "type": "string"
          },
          "critical": {
            "type": "integer",
            "minimum": 0
          },
          "high": {
            "type": "integer",
            "minimum": 0
          },
          "medium": {
            "type": "integer",
            "minimum": 0
          },
          "low": {
            "type": "integer",
            "minimum": 0
          },
          "total": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "SbomCreateRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1
          },
          "version": {
            "type": "string"
          },
          "assetId": {
            "type": "string"
          },
          "repoUrl": {
            "type": "string"
          },
          "branch": {
            "type": "string"
          }
        }
      },
      "SbomUploadForm": {
        "type": "object",
        "required": [
          "file"
        ],
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "description": "Dependency manifest (required), at most 5 MB."
          },
          "name": {
            "type": "string",
            "description": "SBOM name. Defaults to the uploaded filename."
          },
          "version": {
            "type": "string",
            "description": "Optional version label."
          }
        }
      },
      "FindingStatusRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "open",
              "mitigated",
              "accepted_risk",
              "false_positive",
              "fixed"
            ]
          },
          "remediationNotes": {
            "type": "string"
          }
        }
      },
      "VendorRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "type",
          "riskTier",
          "assessmentStatus"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1
          },
          "website": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "oss",
              "commercial",
              "internal"
            ]
          },
          "riskTier": {
            "type": "integer",
            "enum": [
              1,
              2,
              3
            ]
          },
          "assessmentStatus": {
            "type": "string",
            "enum": [
              "not_started",
              "in_progress",
              "completed"
            ]
          },
          "notes": {
            "type": "string"
          }
        }
      },
      "SbomResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Sbom"
          }
        }
      },
      "SbomListResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Sbom"
            }
          }
        }
      },
      "ComponentListResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SbomComponent"
            }
          }
        }
      },
      "FindingListResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VulnFinding"
            }
          }
        }
      },
      "SeveritySummaryResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SeveritySummary"
          }
        }
      },
      "VendorResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SoftwareVendor"
          }
        }
      },
      "VendorListResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SoftwareVendor"
            }
          }
        }
      },
      "VendorRiskSummaryListResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VendorRiskSummary"
            }
          }
        }
      },
      "DeletedResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "deleted"
            ],
            "properties": {
              "deleted": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "UpdatedResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "updated"
            ],
            "properties": {
              "updated": {
                "type": "boolean"
              }
            }
          }
        }
      },
      "SscsErrorEnvelope": {
        "type": "object",
        "description": "Error body. data is always null.",
        "required": [
          "data",
          "error"
        ],
        "properties": {
          "data": {
            "type": "object",
            "nullable": true,
            "description": "Always null."
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "id": {
                "type": "string",
                "description": "Correlation id to quote to support."
              },
              "code": {
                "type": "string",
                "enum": [
                  "UNAUTHORIZED",
                  "INVALID_TOKEN",
                  "FORBIDDEN",
                  "INSUFFICIENT_SCOPE",
                  "FEATURE_GATED",
                  "BILLING_UNAVAILABLE",
                  "RATE_LIMITED",
                  "VALIDATION_FAILED",
                  "INVALID_REQUEST",
                  "INVALID_STATUS",
                  "INVALID_SEVERITY",
                  "MISSING_FILE",
                  "UNSUPPORTED_FORMAT",
                  "PARSE_ERROR",
                  "FILE_TOO_LARGE",
                  "PAYLOAD_TOO_LARGE",
                  "NOT_FOUND",
                  "DB_ERROR",
                  "VALIDATION_ERROR"
                ]
              },
              "message": {
                "type": "string",
                "description": "User-safe message."
              },
              "args": {
                "type": "object",
                "additionalProperties": true,
                "description": "Structured details, for example the feature behind a 402."
              }
            }
          }
        }
      },
      "TemplateStatus": {
        "type": "string",
        "description": "draft and submitted are open (editable or awaiting approval); published is the live version; archived is retired.",
        "enum": [
          "draft",
          "submitted",
          "published",
          "archived"
        ]
      },
      "LocalizedText": {
        "type": "object",
        "description": "Text per locale. `en` is required; `ru` and `he` fall back to `en` when blank. At most 500 characters per locale (2000 for a description); HTML is rejected.",
        "required": [
          "en"
        ],
        "properties": {
          "en": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          },
          "ru": {
            "type": "string",
            "maxLength": 500
          },
          "he": {
            "type": "string",
            "maxLength": 500
          }
        }
      },
      "TemplateLimits": {
        "type": "object",
        "description": "The structural caps the server enforces.",
        "required": [
          "maxSections",
          "maxQuestionsPerSection",
          "maxQuestionsPerTemplate",
          "maxOptionsPerQuestion"
        ],
        "properties": {
          "maxSections": {
            "type": "integer",
            "maximum": 20
          },
          "maxQuestionsPerSection": {
            "type": "integer",
            "maximum": 50
          },
          "maxQuestionsPerTemplate": {
            "type": "integer",
            "maximum": 300
          },
          "maxOptionsPerQuestion": {
            "type": "integer",
            "maximum": 12
          }
        }
      },
      "TemplatePermissions": {
        "type": "object",
        "description": "What the caller may do with this version right now.",
        "required": [
          "canEdit",
          "canSubmit",
          "canWithdraw",
          "canReject",
          "canPublish",
          "canSetDefault",
          "canArchive",
          "canDelete",
          "publishBlockedReason"
        ],
        "properties": {
          "canEdit": {
            "type": "boolean"
          },
          "canSubmit": {
            "type": "boolean"
          },
          "canWithdraw": {
            "type": "boolean"
          },
          "canReject": {
            "type": "boolean"
          },
          "canPublish": {
            "type": "boolean",
            "nullable": true
          },
          "canSetDefault": {
            "type": "boolean"
          },
          "canArchive": {
            "type": "boolean"
          },
          "canDelete": {
            "type": "boolean"
          },
          "publishBlockedReason": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "ResponseRequirement": {
        "type": "object",
        "description": "The question is shown only when the question `questionId` was answered with one of `anyOption`.",
        "required": [
          "questionId",
          "anyOption"
        ],
        "properties": {
          "questionId": {
            "type": "string"
          },
          "anyOption": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "TemplateOption": {
        "type": "object",
        "required": [
          "optionId",
          "labelKey"
        ],
        "properties": {
          "optionId": {
            "type": "string"
          },
          "labelKey": {
            "type": "string",
            "description": "Built-in text key; authored options carry `label` instead."
          },
          "notApplicable": {
            "type": "boolean"
          },
          "label": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "riskValue": {
            "type": "integer",
            "minimum": 0,
            "maximum": 4,
            "description": "Scoring: 0 (no risk) to 4."
          },
          "findingSeverity": {
            "type": "string",
            "enum": [
              "info",
              "low",
              "medium",
              "high",
              "critical"
            ]
          },
          "findingKey": {
            "type": "string"
          },
          "finding": {
            "$ref": "#/components/schemas/LocalizedText"
          }
        }
      },
      "TemplateQuestion": {
        "type": "object",
        "required": [
          "questionId",
          "textKey",
          "answerType",
          "required",
          "modes",
          "domain"
        ],
        "properties": {
          "questionId": {
            "type": "string"
          },
          "textKey": {
            "type": "string",
            "description": "Built-in text key; authored questions carry `text` instead."
          },
          "helpKey": {
            "type": "string"
          },
          "answerType": {
            "type": "string",
            "enum": [
              "text",
              "email",
              "phone",
              "textarea",
              "single_select",
              "multi_select"
            ]
          },
          "required": {
            "type": "boolean"
          },
          "modes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "domain": {
            "type": "string",
            "enum": [
              "",
              "governance",
              "privacy",
              "access",
              "operations",
              "resilience",
              "supply_chain",
              "contractual"
            ]
          },
          "syncTarget": {
            "type": "string"
          },
          "evidenceHintKey": {
            "type": "string"
          },
          "options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateOption"
            }
          },
          "requiresVendorTypes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "allowNotApplicable": {
            "type": "boolean"
          },
          "requiresResponses": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ResponseRequirement"
            }
          },
          "text": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "help": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "evidenceHint": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "authored": {
            "type": "boolean"
          },
          "weight": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10,
            "description": "Scoring weight."
          },
          "controlIds": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "TemplateSection": {
        "type": "object",
        "required": [
          "sectionId",
          "titleKey",
          "order",
          "questions"
        ],
        "properties": {
          "sectionId": {
            "type": "string"
          },
          "titleKey": {
            "type": "string"
          },
          "title": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "order": {
            "type": "integer"
          },
          "questions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateQuestion"
            }
          }
        }
      },
      "AssessmentTemplate": {
        "type": "object",
        "description": "One questionnaire version with its content.",
        "required": [
          "templateId",
          "templateKey",
          "version",
          "titleKey",
          "modes",
          "active",
          "createdAt",
          "updatedAt",
          "sections",
          "limits"
        ],
        "properties": {
          "templateId": {
            "type": "string"
          },
          "templateKey": {
            "type": "string",
            "description": "Shared by all versions of the questionnaire."
          },
          "version": {
            "type": "integer",
            "description": "0 for an open draft."
          },
          "titleKey": {
            "type": "string"
          },
          "descriptionKey": {
            "type": "string"
          },
          "title": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "description": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "modes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "source": {
            "type": "string",
            "enum": [
              "builtin",
              "authored"
            ]
          },
          "status": {
            "$ref": "#/components/schemas/TemplateStatus"
          },
          "active": {
            "type": "boolean"
          },
          "isDefault": {
            "type": "boolean"
          },
          "questionCount": {
            "type": "integer"
          },
          "revision": {
            "type": "integer",
            "description": "Send with an edit; changes on every structural edit."
          },
          "contentHash": {
            "type": "string"
          },
          "clonedFromKey": {
            "type": "string"
          },
          "clonedFromVersion": {
            "type": "integer"
          },
          "parentVersion": {
            "type": "integer"
          },
          "publishedAt": {
            "type": "string",
            "format": "date-time"
          },
          "publishedBy": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdBy": {
            "type": "string"
          },
          "updatedBy": {
            "type": "string"
          },
          "lastEditedBy": {
            "type": "string"
          },
          "lastEditedAt": {
            "type": "string",
            "format": "date-time"
          },
          "submittedBy": {
            "type": "string"
          },
          "submittedAt": {
            "type": "string",
            "format": "date-time"
          },
          "submitterNote": {
            "type": "string"
          },
          "rejectedBy": {
            "type": "string"
          },
          "rejectedAt": {
            "type": "string",
            "format": "date-time"
          },
          "rejectionReason": {
            "type": "string"
          },
          "sections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateSection"
            }
          },
          "limits": {
            "$ref": "#/components/schemas/TemplateLimits"
          },
          "permissions": {
            "$ref": "#/components/schemas/TemplatePermissions"
          }
        }
      },
      "TemplateListItem": {
        "type": "object",
        "description": "A questionnaire row without sections.",
        "required": [
          "templateId",
          "templateKey",
          "version",
          "titleKey",
          "active",
          "updatedAt",
          "permissions"
        ],
        "properties": {
          "templateId": {
            "type": "string"
          },
          "templateKey": {
            "type": "string"
          },
          "version": {
            "type": "integer"
          },
          "titleKey": {
            "type": "string"
          },
          "descriptionKey": {
            "type": "string"
          },
          "title": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "description": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "source": {
            "type": "string",
            "enum": [
              "builtin",
              "authored"
            ]
          },
          "status": {
            "$ref": "#/components/schemas/TemplateStatus"
          },
          "active": {
            "type": "boolean"
          },
          "isDefault": {
            "type": "boolean"
          },
          "questionCount": {
            "type": "integer"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedBy": {
            "type": "string"
          },
          "permissions": {
            "$ref": "#/components/schemas/TemplatePermissions"
          }
        }
      },
      "TemplateViolation": {
        "type": "object",
        "description": "A rule that blocks submitting or publishing. `path` locates the field, for example `sections[0].questions[2].weight`.",
        "required": [
          "code",
          "path",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "V1 to V12."
          },
          "path": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "TemplateWarning": {
        "type": "object",
        "description": "A non-blocking finding. The code is the contract; `parameters` carries its values.",
        "required": [
          "code",
          "path",
          "parameters"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "W1_NO_ZERO_RISK_OPTION, W2_MISSING_TRANSLATION, W3_NO_CONTROL_IDS, W4_TOP_OF_SCALE_SKEW, W5_ALL_OPTIONS_ZERO_RISK, or (preview only) W6_WEIGHT_RAISED_3X."
          },
          "path": {
            "type": "string"
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "IntDelta": {
        "type": "object",
        "required": [
          "before",
          "after",
          "change"
        ],
        "properties": {
          "before": {
            "type": "integer"
          },
          "after": {
            "type": "integer"
          },
          "change": {
            "type": "integer"
          }
        }
      },
      "ModeIntDelta": {
        "type": "object",
        "required": [
          "mode",
          "before",
          "after",
          "change",
          "unloseableBefore",
          "unloseableAfter",
          "deltaPct"
        ],
        "properties": {
          "mode": {
            "type": "string"
          },
          "before": {
            "type": "integer"
          },
          "after": {
            "type": "integer"
          },
          "change": {
            "type": "integer"
          },
          "unloseableBefore": {
            "type": "integer"
          },
          "unloseableAfter": {
            "type": "integer"
          },
          "deltaPct": {
            "type": "number"
          }
        }
      },
      "ScoreableQuestionDelta": {
        "type": "object",
        "required": [
          "before",
          "after",
          "change",
          "added",
          "removed"
        ],
        "properties": {
          "before": {
            "type": "integer"
          },
          "after": {
            "type": "integer"
          },
          "change": {
            "type": "integer"
          },
          "added": {
            "type": "integer"
          },
          "removed": {
            "type": "integer"
          }
        }
      },
      "WeightChange": {
        "type": "object",
        "required": [
          "questionId",
          "sectionId",
          "text",
          "before",
          "after",
          "zeroRiskOnly"
        ],
        "properties": {
          "questionId": {
            "type": "string"
          },
          "sectionId": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "before": {
            "type": "integer"
          },
          "after": {
            "type": "integer"
          },
          "zeroRiskOnly": {
            "type": "boolean"
          }
        }
      },
      "RiskValueChange": {
        "type": "object",
        "required": [
          "questionId",
          "optionId",
          "label",
          "before",
          "after"
        ],
        "properties": {
          "questionId": {
            "type": "string"
          },
          "optionId": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "before": {
            "type": "integer"
          },
          "after": {
            "type": "integer"
          }
        }
      },
      "SeverityChange": {
        "type": "object",
        "required": [
          "questionId",
          "optionId",
          "label",
          "before",
          "after",
          "downgrade"
        ],
        "properties": {
          "questionId": {
            "type": "string"
          },
          "optionId": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "before": {
            "type": "string"
          },
          "after": {
            "type": "string"
          },
          "downgrade": {
            "type": "boolean"
          },
          "removed": {
            "type": "boolean",
            "description": "True when the option or its question no longer exists in the draft."
          }
        }
      },
      "QuestionRef": {
        "type": "object",
        "required": [
          "questionId",
          "sectionId",
          "text",
          "weight",
          "scoreable"
        ],
        "properties": {
          "questionId": {
            "type": "string"
          },
          "sectionId": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "weight": {
            "type": "integer"
          },
          "scoreable": {
            "type": "boolean"
          }
        }
      },
      "ChangeActor": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "description": "user, api_token or mcp."
          },
          "userId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "tokenId": {
            "type": "string"
          },
          "tokenName": {
            "type": "string"
          },
          "surface": {
            "type": "string",
            "description": "console, api_token or mcp."
          }
        }
      },
      "TemplateChange": {
        "type": "object",
        "description": "One row of the approval ledger.",
        "required": [
          "kind",
          "questionId",
          "sectionId",
          "textEn",
          "before",
          "after",
          "shareBefore",
          "shareAfter",
          "shareMode",
          "allOptionsZeroRisk",
          "reducesRisk",
          "tier"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "description": "weight, riskValue, severity, required, allowNa, questionAdded, questionRemoved, optionAdded, optionRemoved, conditionalRemoved or text."
          },
          "questionId": {
            "type": "string"
          },
          "sectionId": {
            "type": "string"
          },
          "optionId": {
            "type": "string"
          },
          "textEn": {
            "type": "string"
          },
          "before": {
            "nullable": true,
            "description": "Previous value; its type depends on `kind`. Null on questionAdded, questionRemoved, optionAdded and optionRemoved rows."
          },
          "after": {
            "nullable": true,
            "description": "New value; its type depends on `kind`. Null on questionAdded, questionRemoved, optionAdded and optionRemoved rows."
          },
          "shareBefore": {
            "type": "number"
          },
          "shareAfter": {
            "type": "number"
          },
          "shareMode": {
            "type": "string"
          },
          "allOptionsZeroRisk": {
            "type": "boolean"
          },
          "reducesRisk": {
            "type": "boolean"
          },
          "tier": {
            "type": "string",
            "enum": [
              "notice",
              "significant",
              "severe"
            ]
          },
          "actor": {
            "$ref": "#/components/schemas/ChangeActor"
          }
        }
      },
      "TemplateScoringImpact": {
        "type": "object",
        "description": "What publishing the draft would change in scoring, against the baseline version.",
        "required": [
          "fromVersion",
          "toVersion",
          "baselineIsBuiltin",
          "baselineKey",
          "maxPenalty",
          "criticalOptionCount",
          "scoreableQuestionCount",
          "weightChanges",
          "riskValueChanges",
          "severityChanges",
          "addedQuestions",
          "removedQuestions",
          "changes",
          "requiresAcknowledgement",
          "acknowledgementReasons",
          "acknowledgementRowCount"
        ],
        "properties": {
          "fromVersion": {
            "type": "integer",
            "nullable": true
          },
          "toVersion": {
            "type": "integer"
          },
          "baselineIsBuiltin": {
            "type": "boolean"
          },
          "baselineKey": {
            "type": "string"
          },
          "maxPenalty": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModeIntDelta"
            }
          },
          "criticalOptionCount": {
            "$ref": "#/components/schemas/IntDelta"
          },
          "scoreableQuestionCount": {
            "$ref": "#/components/schemas/ScoreableQuestionDelta"
          },
          "weightChanges": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WeightChange"
            }
          },
          "riskValueChanges": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RiskValueChange"
            }
          },
          "severityChanges": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SeverityChange"
            }
          },
          "addedQuestions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QuestionRef"
            }
          },
          "removedQuestions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QuestionRef"
            }
          },
          "changes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateChange"
            }
          },
          "requiresAcknowledgement": {
            "type": "boolean",
            "description": "True when a person must acknowledge a risk reduction to publish."
          },
          "acknowledgementReasons": {
            "type": "array",
            "items": {
              "type": "string",
              "description": "SEVERITY_DOWNGRADE or SCOREABLE_QUESTIONS_HALVED."
            }
          },
          "acknowledgementRowCount": {
            "type": "integer"
          }
        }
      },
      "TemplateFieldDiff": {
        "type": "object",
        "required": [
          "field",
          "before",
          "after"
        ],
        "properties": {
          "field": {
            "type": "string"
          },
          "before": {
            "description": "Value in the first version."
          },
          "after": {
            "description": "Value in the second version."
          }
        }
      },
      "TemplateDiffRow": {
        "type": "object",
        "required": [
          "kind",
          "questionId",
          "sectionId"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "questionAdded",
              "questionRemoved",
              "questionModified",
              "optionAdded",
              "optionRemoved",
              "optionModified"
            ]
          },
          "questionId": {
            "type": "string"
          },
          "sectionId": {
            "type": "string"
          },
          "optionId": {
            "type": "string"
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateFieldDiff"
            }
          },
          "referencedByAssessments": {
            "type": "integer",
            "description": "For questionRemoved: existing assessments holding an answer to it."
          }
        }
      },
      "TemplateDiff": {
        "type": "object",
        "required": [
          "templateKey",
          "fromVersion",
          "toVersion",
          "rows"
        ],
        "properties": {
          "templateKey": {
            "type": "string"
          },
          "fromVersion": {
            "type": "integer"
          },
          "toVersion": {
            "type": "integer"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateDiffRow"
            }
          }
        }
      },
      "TemplateValidate": {
        "type": "object",
        "required": [
          "violations",
          "warnings"
        ],
        "properties": {
          "violations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateViolation"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateWarning"
            }
          }
        }
      },
      "TemplatePreview": {
        "type": "object",
        "required": [
          "impact",
          "violations",
          "warnings",
          "permissions"
        ],
        "properties": {
          "impact": {
            "$ref": "#/components/schemas/TemplateScoringImpact"
          },
          "violations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateViolation"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateWarning"
            }
          },
          "permissions": {
            "$ref": "#/components/schemas/TemplatePermissions"
          }
        }
      },
      "TemplateCreateRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "firstSectionTitle": {
            "$ref": "#/components/schemas/LocalizedText"
          }
        }
      },
      "TemplateCloneRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "sourceTemplateId",
          "name"
        ],
        "properties": {
          "sourceTemplateId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "The built-in questionnaire id or a templateId of the organization."
          },
          "name": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "setAsDefault": {
            "type": "boolean"
          }
        }
      },
      "TemplateMetaPatchRequest": {
        "type": "object",
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "title": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "description": {
            "type": "object",
            "description": "Localised description, at most 2000 characters per locale; `en` is optional.",
            "additionalProperties": false,
            "properties": {
              "en": {
                "type": "string",
                "maxLength": 2000
              },
              "ru": {
                "type": "string",
                "maxLength": 2000
              },
              "he": {
                "type": "string",
                "maxLength": 2000
              }
            }
          },
          "modes": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            }
          },
          "revision": {
            "type": "integer",
            "minimum": 0,
            "description": "The draft revision; or send it as If-Match."
          }
        }
      },
      "TemplateSectionCreateRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "title",
          "revision"
        ],
        "properties": {
          "title": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "revision": {
            "type": "integer",
            "minimum": 0,
            "description": "The draft revision; or send it as If-Match."
          }
        }
      },
      "TemplateSectionPatchRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "title"
        ],
        "properties": {
          "title": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "revision": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "RevisionRequest": {
        "type": "object",
        "properties": {
          "revision": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "LocalizedLongText": {
        "type": "object",
        "description": "Text per locale, at most 2000 characters per locale; HTML is rejected. All locales are optional.",
        "additionalProperties": false,
        "properties": {
          "en": {
            "type": "string",
            "maxLength": 2000
          },
          "ru": {
            "type": "string",
            "maxLength": 2000
          },
          "he": {
            "type": "string",
            "maxLength": 2000
          }
        }
      },
      "TemplateOptionInput": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "label",
          "riskValue"
        ],
        "properties": {
          "label": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "riskValue": {
            "type": "integer",
            "minimum": 0,
            "maximum": 4,
            "description": "Scoring: 0 (no risk) to 4."
          },
          "findingSeverity": {
            "type": "string",
            "enum": [
              "",
              "info",
              "low",
              "medium",
              "high",
              "critical"
            ]
          },
          "finding": {
            "$ref": "#/components/schemas/LocalizedLongText"
          },
          "notApplicable": {
            "type": "boolean"
          }
        }
      },
      "TemplateQuestionCreateRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "sectionId",
          "answerType",
          "text"
        ],
        "properties": {
          "sectionId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "text": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "help": {
            "$ref": "#/components/schemas/LocalizedLongText"
          },
          "evidenceHint": {
            "$ref": "#/components/schemas/LocalizedLongText"
          },
          "answerType": {
            "type": "string",
            "enum": [
              "text",
              "email",
              "phone",
              "textarea",
              "single_select",
              "multi_select"
            ]
          },
          "required": {
            "type": "boolean"
          },
          "modes": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            }
          },
          "domain": {
            "type": "string",
            "enum": [
              "",
              "governance",
              "privacy",
              "access",
              "operations",
              "resilience",
              "supply_chain",
              "contractual"
            ]
          },
          "weight": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10,
            "description": "Scoring weight."
          },
          "controlIds": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            }
          },
          "allowNotApplicable": {
            "type": "boolean"
          },
          "options": {
            "type": "array",
            "maxItems": 12,
            "description": "Required (2 to 12) for single_select and multi_select, empty or absent for every other answer type.",
            "items": {
              "$ref": "#/components/schemas/TemplateOptionInput"
            }
          },
          "revision": {
            "type": "integer",
            "minimum": 0,
            "description": "The draft revision, honoured when sent; or send it as If-Match."
          }
        }
      },
      "TemplateQuestionPatchRequest": {
        "type": "object",
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "text": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "help": {
            "$ref": "#/components/schemas/LocalizedLongText"
          },
          "evidenceHint": {
            "$ref": "#/components/schemas/LocalizedLongText"
          },
          "answerType": {
            "type": "string",
            "enum": [
              "text",
              "email",
              "phone",
              "textarea",
              "single_select",
              "multi_select"
            ]
          },
          "required": {
            "type": "boolean"
          },
          "modes": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            }
          },
          "domain": {
            "type": "string",
            "enum": [
              "",
              "governance",
              "privacy",
              "access",
              "operations",
              "resilience",
              "supply_chain",
              "contractual"
            ]
          },
          "weight": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10,
            "description": "Scoring weight."
          },
          "controlIds": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            }
          },
          "allowNotApplicable": {
            "type": "boolean"
          },
          "revision": {
            "type": "integer",
            "minimum": 0,
            "description": "Accepted and ignored: a field edit does not check the revision."
          }
        }
      },
      "TemplateOptionCreateRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "label",
          "riskValue",
          "revision"
        ],
        "properties": {
          "label": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "riskValue": {
            "type": "integer",
            "minimum": 0,
            "maximum": 4,
            "description": "Scoring: 0 (no risk) to 4."
          },
          "findingSeverity": {
            "type": "string",
            "enum": [
              "",
              "info",
              "low",
              "medium",
              "high",
              "critical"
            ]
          },
          "finding": {
            "$ref": "#/components/schemas/LocalizedLongText"
          },
          "notApplicable": {
            "type": "boolean"
          },
          "revision": {
            "type": "integer",
            "minimum": 0,
            "description": "The draft revision; or send it as If-Match."
          }
        }
      },
      "TemplateOptionPatchRequest": {
        "type": "object",
        "additionalProperties": false,
        "minProperties": 1,
        "properties": {
          "label": {
            "$ref": "#/components/schemas/LocalizedText"
          },
          "riskValue": {
            "type": "integer",
            "minimum": 0,
            "maximum": 4,
            "description": "Scoring: 0 (no risk) to 4."
          },
          "findingSeverity": {
            "type": "string",
            "enum": [
              "",
              "info",
              "low",
              "medium",
              "high",
              "critical"
            ]
          },
          "finding": {
            "$ref": "#/components/schemas/LocalizedLongText"
          },
          "notApplicable": {
            "type": "boolean"
          },
          "revision": {
            "type": "integer",
            "minimum": 0,
            "description": "Accepted and ignored: a field edit does not check the revision."
          },
          "acknowledgeRiskReduction": {
            "type": "boolean",
            "default": false,
            "description": "A person acknowledges lowering a critical finding severity. A token that sends true is refused with 403 HUMAN_APPROVAL_REQUIRED."
          },
          "riskReductionReason": {
            "type": "string",
            "enum": [
              "control_not_applicable",
              "duplicate_question",
              "severity_set_wrongly",
              "replaced_by_another_question",
              "other"
            ],
            "description": "Required when acknowledgeRiskReduction is true."
          },
          "riskReductionJustification": {
            "type": "string",
            "minLength": 20,
            "maxLength": 500,
            "description": "Required when acknowledgeRiskReduction is true."
          }
        }
      },
      "TemplateSubmitRequest": {
        "type": "object",
        "additionalProperties": false,
        "description": "The revision is required by the server (400 VALIDATION_FAILED without it, in the body or as If-Match).",
        "properties": {
          "revision": {
            "type": "integer",
            "minimum": 0,
            "description": "The draft revision; or send it as If-Match."
          },
          "note": {
            "type": "string",
            "maxLength": 500,
            "description": "Shown to the approver."
          }
        }
      },
      "TemplateTranslateRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "sources",
          "target"
        ],
        "properties": {
          "sources": {
            "type": "object",
            "additionalProperties": false,
            "description": "The text to translate from, per language; at least one language other than `target` must have text.",
            "properties": {
              "en": {
                "type": "string",
                "maxLength": 2000
              },
              "ru": {
                "type": "string",
                "maxLength": 2000
              },
              "he": {
                "type": "string",
                "maxLength": 2000
              }
            }
          },
          "target": {
            "type": "string",
            "enum": [
              "en",
              "ru",
              "he"
            ]
          }
        }
      },
      "TemplateTranslateResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "text"
            ],
            "properties": {
              "text": {
                "type": "string",
                "description": "The translation. Nothing is saved."
              }
            }
          }
        }
      },
      "TemplateResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/AssessmentTemplate"
          }
        }
      },
      "TemplateVersionResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/AssessmentTemplate"
          },
          "meta": {
            "type": "object",
            "required": [
              "contentHashVerified"
            ],
            "properties": {
              "contentHashVerified": {
                "type": "boolean",
                "description": "False when the stored content no longer matches the recorded hash, or there is none (a draft)."
              }
            }
          }
        }
      },
      "TemplateListResponse": {
        "type": "object",
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TemplateListItem"
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "total"
            ],
            "properties": {
              "total": {
                "type": "integer"
              },
              "limit": {
                "type": "integer"
              },
              "offset": {
                "type": "integer"
              }
            }
          }
        }
      },
      "TemplateDiffResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/TemplateDiff"
          }
        }
      },
      "TemplateValidateResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/TemplateValidate"
          }
        }
      },
      "TemplatePreviewResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/TemplatePreview"
          }
        }
      },
      "SupplierTemplatesErrorEnvelope": {
        "type": "object",
        "description": "Error body. data is always null.",
        "required": [
          "data",
          "error"
        ],
        "properties": {
          "data": {
            "type": "object",
            "nullable": true,
            "description": "Always null."
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "id": {
                "type": "string",
                "description": "Correlation id to quote to support."
              },
              "code": {
                "type": "string",
                "enum": [
                  "UNAUTHORIZED",
                  "INVALID_TOKEN",
                  "FORBIDDEN",
                  "INSUFFICIENT_SCOPE",
                  "INSUFFICIENT_ROLE",
                  "HUMAN_APPROVAL_REQUIRED",
                  "FEATURE_GATED",
                  "BILLING_UNAVAILABLE",
                  "RATE_LIMITED",
                  "VALIDATION_FAILED",
                  "PAYLOAD_TOO_LARGE",
                  "NOT_FOUND",
                  "SECTION_NOT_FOUND",
                  "TEMPLATE_LIMIT_REACHED",
                  "STALE_REVISION",
                  "TEMPLATE_PUBLISHED",
                  "TEMPLATE_SUBMITTED",
                  "TEMPLATE_ARCHIVED",
                  "NOT_A_DRAFT",
                  "DRAFT_EXISTS",
                  "BUILTIN_IMMUTABLE",
                  "SECTION_LIMIT_REACHED",
                  "TEMPLATE_SIZE_LIMIT_REACHED",
                  "SECTION_REFERENCED",
                  "QUESTION_IS_GATING_TRIGGER",
                  "QUESTION_NOT_FOUND",
                  "OPTION_NOT_FOUND",
                  "QUESTION_LIMIT_REACHED",
                  "OPTION_LIMIT_REACHED",
                  "OPTION_MINIMUM_REACHED",
                  "OPTIONS_NOT_ALLOWED",
                  "OPTION_REFERENCED",
                  "QUESTION_REFERENCED",
                  "TEMPLATE_INVALID",
                  "ALREADY_SUBMITTED",
                  "NOT_SUBMITTED",
                  "RISK_REDUCTION_NOT_ACKNOWLEDGED",
                  "NOTHING_TO_TRANSLATE",
                  "AI_UNAVAILABLE",
                  "AI_FAILED",
                  "DB_ERROR"
                ]
              },
              "message": {
                "type": "string",
                "description": "User-safe message."
              },
              "args": {
                "type": "object",
                "additionalProperties": true,
                "description": "Structured details: the feature behind a 402, `current` on a 409 STALE_REVISION or a state conflict, `dependents` on SECTION_REFERENCED, QUESTION_REFERENCED and OPTION_REFERENCED, `violations` on TEMPLATE_INVALID, `retryAfterSeconds` on a 429."
              }
            }
          }
        }
      },
      "Scope": {
        "type": "string",
        "enum": [
          "sbom:read",
          "sbom:write",
          "mcp:read",
          "mcp:write",
          "supplier_template:read",
          "supplier_template:write",
          "pii:read",
          "jml:read",
          "asset:read",
          "risk:read",
          "supplier:read",
          "iso:read",
          "compliance:read",
          "evidence:read",
          "access_review:read",
          "employee:read",
          "audit_log:read",
          "audit_log:verify"
        ],
        "description": "What the token may do. sbom:write, mcp:write and supplier_template:write imply their read scope; no other scope implies another. See Access Model & Scopes and GET /tokens/scopes."
      },
      "ApiToken": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "tokenId",
          "name",
          "prefix",
          "scopes",
          "createdBy",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "tokenId": {
            "type": "string",
            "description": "Token id."
          },
          "name": {
            "type": "string",
            "description": "Name given at creation."
          },
          "prefix": {
            "type": "string",
            "description": "First visible characters of the secret, to recognise the token."
          },
          "scopes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Scope"
            }
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "Expiry; absent for a token that does not expire."
          },
          "revokedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Set once the token is revoked."
          },
          "revokedBy": {
            "type": "string",
            "description": "User id of who revoked it."
          },
          "lastUsedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Last successful use; absent if never used."
          },
          "suspendedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Set when the token was suspended because its creator no longer holds the role its scopes require. A suspended token is refused like a revoked one and is not resumed."
          },
          "suspendedReason": {
            "type": "string",
            "description": "Why the token was suspended."
          },
          "activity": {
            "$ref": "#/components/schemas/TokenActivity"
          },
          "createdBy": {
            "type": "string",
            "description": "User id of the creator."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreatedToken": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "tokenId",
          "name",
          "prefix",
          "scopes",
          "createdBy",
          "createdAt",
          "updatedAt",
          "tokenValue"
        ],
        "properties": {
          "tokenId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "type": "string"
          },
          "scopes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Scope"
            }
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "revokedAt": {
            "type": "string",
            "format": "date-time"
          },
          "revokedBy": {
            "type": "string"
          },
          "lastUsedAt": {
            "type": "string",
            "format": "date-time"
          },
          "suspendedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Set when the token was suspended because its creator no longer holds the role its scopes require. A suspended token is refused like a revoked one and is not resumed."
          },
          "suspendedReason": {
            "type": "string",
            "description": "Why the token was suspended."
          },
          "activity": {
            "$ref": "#/components/schemas/TokenActivity"
          },
          "createdBy": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "tokenValue": {
            "type": "string",
            "description": "The secret. Returned only in this response; send it as `Authorization: Bearer <token>`."
          }
        }
      },
      "CreateTokenRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "scopes"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "A name that says where the token is used."
          },
          "scopes": {
            "type": "array",
            "minItems": 1,
            "maxItems": 40,
            "description": "Explicit scope names from GET /tokens/scopes. Unknown names, wildcards and bundle names are refused with SCOPE_INVALID.",
            "items": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_:*.-]{1,64}$"
            }
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Future expiry. Required, within the scope maximum, for scopes whose catalogue entry has requiresExpiry (for example pii:read within 90 days, jml:read within 365 days, supplier_template:write)."
          }
        }
      },
      "TokenActivity": {
        "type": "object",
        "additionalProperties": false,
        "description": "Usage of the token on the current UTC day. Absent until the token has been used.",
        "required": [
          "day",
          "requests",
          "rows",
          "distinctRoutes",
          "lastIp",
          "lastRouteId"
        ],
        "properties": {
          "day": {
            "type": "string",
            "description": "UTC date, YYYY-MM-DD."
          },
          "requests": {
            "type": "integer",
            "description": "Requests made that day."
          },
          "rows": {
            "type": "integer",
            "description": "Data rows returned that day."
          },
          "distinctRoutes": {
            "type": "integer",
            "description": "Number of distinct routes called that day (capped at 50)."
          },
          "lastIp": {
            "type": "string",
            "description": "Client address of the last request."
          },
          "lastRouteId": {
            "type": "string",
            "description": "Route template of the last request."
          }
        }
      },
      "CatalogEntry": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "scope",
          "group",
          "resource",
          "requiresExpiry",
          "maxExpiryDays",
          "creatorRoles",
          "enabled"
        ],
        "properties": {
          "scope": {
            "type": "string",
            "description": "The scope name to send in POST /tokens."
          },
          "group": {
            "type": "string"
          },
          "resource": {
            "type": "string"
          },
          "requiresExpiry": {
            "type": "boolean"
          },
          "maxExpiryDays": {
            "type": "integer",
            "description": "Maximum lifetime in days; 0 for no maximum."
          },
          "creatorRoles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Roles that may grant the scope."
          },
          "enabled": {
            "type": "boolean",
            "description": "Whether its public routes are live."
          }
        }
      },
      "ScopeCatalogResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CatalogEntry"
            }
          }
        }
      },
      "TokenListResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiToken"
            }
          }
        }
      },
      "CreatedTokenResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/CreatedToken"
          }
        }
      },
      "TokensErrorEnvelope": {
        "type": "object",
        "description": "Error body. data is always null.",
        "required": [
          "data",
          "error"
        ],
        "properties": {
          "data": {
            "type": "object",
            "nullable": true,
            "description": "Always null."
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "id": {
                "type": "string",
                "description": "Correlation id to quote to support."
              },
              "code": {
                "type": "string",
                "enum": [
                  "UNAUTHORIZED",
                  "FORBIDDEN",
                  "SUPPORT_SESSION_NO_MINT",
                  "INVALID_BODY",
                  "VALIDATION_FAILED",
                  "SCOPE_INVALID",
                  "SCOPE_UNAVAILABLE",
                  "OWNER_REQUIRED",
                  "MEMBERSHIP_REQUIRED",
                  "INSUFFICIENT_ROLE",
                  "INVALID_EXPIRY",
                  "EXPIRY_REQUIRED",
                  "EXPIRY_TOO_LONG",
                  "TOKEN_LIMIT_EXCEEDED",
                  "TOKEN_GENERATION_FAILED",
                  "NOT_FOUND",
                  "DB_ERROR"
                ]
              },
              "message": {
                "type": "string",
                "description": "User-safe message."
              },
              "args": {
                "type": "object",
                "additionalProperties": true,
                "description": "Structured details, for example the invalid parameter."
              }
            }
          }
        }
      },
      "HealthResponse": {
        "type": "object",
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "required": [
              "status"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "ok"
                ],
                "description": "Always `ok` when the API answers."
              }
            }
          }
        }
      },
      "HealthErrorEnvelope": {
        "type": "object",
        "description": "Error body. data is always null.",
        "required": [
          "data",
          "error"
        ],
        "properties": {
          "data": {
            "type": "object",
            "nullable": true,
            "description": "Always null."
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "id": {
                "type": "string",
                "description": "Correlation id to quote to support."
              },
              "code": {
                "type": "string",
                "enum": [
                  "RATE_LIMITED"
                ]
              },
              "message": {
                "type": "string",
                "description": "User-safe message."
              }
            }
          }
        }
      },
      "AccessEventTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "assetId": {
            "description": "Asset id, always ast_ (a legacy row's 24-hex id is returned as ast_<hex>).",
            "type": "string"
          },
          "assetLegacyId": {
            "description": "The legacy 24-hex asset id; present only for legacy rows.",
            "type": "string"
          },
          "employeeId": {
            "description": "Employee (empl_ FlakeID).",
            "type": "string"
          },
          "eventId": {
            "description": "Access event id (ace_ FlakeID); the keyset tie-break. Empty for legacy events.",
            "type": "string"
          },
          "eventType": {
            "description": "DETECTED, REVOKED or VERIFIED.",
            "type": "string"
          },
          "occurredAt": {
            "description": "When the audit observed the event (events are append-only; the sync field).",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "eventId",
          "employeeId",
          "assetId",
          "eventType",
          "occurredAt"
        ],
        "type": "object"
      },
      "AccessTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "accessId": {
            "description": "Grant id (acc_ FlakeID); the keyset tie-break.",
            "type": "string"
          },
          "accountState": {
            "description": "Account state reported by the source system: ACTIVE, SUSPENDED, BLOCKED, INVITED or UNKNOWN (default; never guessed).",
            "type": "string"
          },
          "assetCriticality": {
            "description": "Asset criticality (LOW, MEDIUM, HIGH, CRITICAL).",
            "type": "string"
          },
          "assetId": {
            "description": "Asset id, always ast_ (a legacy row's 24-hex id is returned as ast_<hex>); empty when the stored value is not an id.",
            "type": "string"
          },
          "assetLegacyId": {
            "description": "The legacy 24-hex asset id; present only for legacy rows.",
            "type": "string"
          },
          "assetName": {
            "description": "Asset name as entered in AutoCISO (organisation data).",
            "type": "string"
          },
          "dormantDays": {
            "description": "Whole days since the last activity, computed at read time.",
            "type": "integer"
          },
          "employeeId": {
            "description": "Holder of the grant (empl_ FlakeID); empty for an unmatched account. Resolve names with employee_resolve.",
            "type": "string"
          },
          "firstObservedAt": {
            "description": "First time AutoCISO observed the grant (not the grant date in the source system).",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "identityType": {
            "description": "HUMAN or SERVICE_ACCOUNT.",
            "type": "string"
          },
          "isDormant": {
            "description": "No activity for 30 days, computed at read time from the dates (it changes without a write, so updatedAt does not move).",
            "type": "boolean"
          },
          "isPrivileged": {
            "description": "true when roleLevel is ADMIN.",
            "type": "boolean"
          },
          "lastDetectedAt": {
            "description": "Last time an audit detected the grant.",
            "format": "date-time",
            "type": "string"
          },
          "lastUsedAt": {
            "description": "Last observed use, when known.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "lastVerifiedAt": {
            "description": "Last verification, when known.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "revocationSource": {
            "description": "Who revoked the grant: MANUAL, SNAPSHOT_REVIEW or MATCH_CORRECTED; empty for an active grant.",
            "type": "string"
          },
          "revokedAt": {
            "description": "When the grant was revoked; null for an active grant.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "riskFactors": {
            "description": "Risk factor codes (closed set: for example TERMINATED_EMPLOYEE_ACCESS, DORMANT_ACCESS, STALE_PRIVILEGE, UNMAPPED_ACCOUNT, ADMIN_LEVEL_ACCESS, CRITICAL_CRITICALITY_ASSET, OWNER_NOT_ASSIGNED). Unknown factors are omitted.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "riskScore": {
            "description": "Risk score (0..100).",
            "type": "integer"
          },
          "roleConfidence": {
            "description": "Confidence of the role classification (0..1).",
            "type": "number"
          },
          "roleLevel": {
            "description": "ADMIN, MANAGER or VIEWER.",
            "type": "string"
          },
          "status": {
            "description": "Lifecycle status (ACTIVE, REVOKED).",
            "type": "string"
          },
          "updatedAt": {
            "description": "Last write to the grant (incremental-sync field); null until the row is backfilled.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "accessId",
          "employeeId",
          "assetId",
          "assetName",
          "assetCriticality",
          "identityType",
          "roleLevel",
          "roleConfidence",
          "isPrivileged",
          "status",
          "firstObservedAt",
          "lastDetectedAt",
          "lastUsedAt",
          "lastVerifiedAt",
          "isDormant",
          "dormantDays",
          "riskScore",
          "riskFactors",
          "updatedAt",
          "accountState",
          "revokedAt",
          "revocationSource"
        ],
        "type": "object"
      },
      "AgreementTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "breachNoticeHours": {
            "description": "Contractual breach notice period in hours, when set.",
            "nullable": true,
            "type": "integer"
          },
          "contractEnd": {
            "description": "Contract end (UTC), when set.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "contractStart": {
            "description": "Contract start (UTC), when set.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "createdAt": {
            "description": "Creation time (UTC).",
            "format": "date-time",
            "type": "string"
          },
          "dataDeletionTimelineDays": {
            "description": "Contractual data deletion timeline in days, when set.",
            "nullable": true,
            "type": "integer"
          },
          "dpaSigned": {
            "description": "A data processing agreement is signed.",
            "type": "boolean"
          },
          "id": {
            "description": "Agreement id (sagr_).",
            "type": "string"
          },
          "rightToAudit": {
            "description": "The contract grants a right to audit.",
            "type": "boolean"
          },
          "sccsVersion": {
            "description": "Standard contractual clauses version (2021-c2c, 2021-c2p, 2021-p2p), when set.",
            "type": "string"
          },
          "securityAddendumSigned": {
            "description": "A security addendum is signed.",
            "type": "boolean"
          },
          "supplierId": {
            "description": "Supplier id (sup_).",
            "type": "string"
          },
          "transferImpactAssessmentRequired": {
            "description": "A transfer impact assessment is required.",
            "type": "boolean"
          },
          "updatedAt": {
            "description": "Last update time (UTC).",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "supplierId",
          "dpaSigned",
          "securityAddendumSigned",
          "rightToAudit",
          "transferImpactAssessmentRequired",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "AssessmentTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "createdAt": {
            "description": "Creation time (UTC).",
            "format": "date-time",
            "type": "string"
          },
          "dueAt": {
            "description": "Next reassessment due (UTC), when set.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "id": {
            "description": "Assessment id (sasm_).",
            "type": "string"
          },
          "mode": {
            "description": "Assessment mode.",
            "type": "string"
          },
          "overallRiskRating": {
            "description": "Overall risk rating (inherent and control gap), when computed.",
            "type": "string"
          },
          "reviewedAt": {
            "description": "Reviewed (UTC), when reviewed.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "riskRating": {
            "description": "Risk rating.",
            "type": "string"
          },
          "score": {
            "description": "Overall score.",
            "type": "integer"
          },
          "sentAt": {
            "description": "Sent to the supplier (UTC), when sent.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "status": {
            "description": "Lifecycle status.",
            "type": "string"
          },
          "submittedAt": {
            "description": "Submitted by the supplier (UTC), when submitted.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "supplierId": {
            "description": "Supplier id (sup_).",
            "type": "string"
          },
          "updatedAt": {
            "description": "Last update time (UTC).",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "supplierId",
          "status",
          "mode",
          "score",
          "riskRating",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "AssetTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "assetName": {
            "description": "Asset name.",
            "type": "string"
          },
          "createdAt": {
            "description": "Creation time (UTC).",
            "format": "date-time",
            "type": "string"
          },
          "criticality": {
            "description": "Business criticality.",
            "type": "string"
          },
          "dataClassification": {
            "description": "Data classification, when set.",
            "type": "string"
          },
          "id": {
            "description": "Asset id (ast_).",
            "type": "string"
          },
          "kind": {
            "description": "COTS, IN_HOUSE, SAAS, OSS, HARDWARE or DOMAIN.",
            "type": "string"
          },
          "legacyId": {
            "description": "Stored legacy id (24 hex), only on assets created before ast_ ids.",
            "type": "string"
          },
          "ownerId": {
            "description": "Owning employee id (empl_), when set.",
            "type": "string"
          },
          "supplierId": {
            "description": "Supplier id (sup_), when set.",
            "type": "string"
          },
          "updatedAt": {
            "description": "Last modification time (UTC); the incremental-sync field.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "assetName",
          "kind",
          "criticality",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "AuditAction": {
        "additionalProperties": false,
        "properties": {
          "code": {
            "type": "string"
          },
          "group": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "group"
        ],
        "type": "object"
      },
      "AuditEntryTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "action": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AuditAction"
              }
            ],
            "description": "Action code and group."
          },
          "actorId": {
            "description": "Actor id: usr_<id> for a user, apitoken:<id> for an API token, system:<job> for the platform; null when the stored value is not an id.",
            "nullable": true,
            "type": "string"
          },
          "chainStatus": {
            "description": "verified, accepted (a reviewed, approved chain exception) or unverified (legacy entry or a break on this page).",
            "type": "string"
          },
          "createdAt": {
            "description": "When the entry was recorded (UTC). The trail is append-only: use createdAt (or seqNum) to sync.",
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "description": "Opaque entry id (24 hex characters); the cursor tie-break.",
            "type": "string"
          },
          "seqNum": {
            "description": "Position in the hash chain; null for legacy entries recorded before the chain.",
            "format": "int64",
            "nullable": true,
            "type": "integer"
          },
          "subjectId": {
            "description": "Subject id; null when the stored value is not an id.",
            "nullable": true,
            "type": "string"
          },
          "subjectType": {
            "description": "Kind of the subject.",
            "type": "string"
          }
        },
        "required": [
          "id",
          "seqNum",
          "createdAt",
          "actorId",
          "action",
          "subjectType",
          "subjectId",
          "chainStatus"
        ],
        "type": "object"
      },
      "ControlMonitorTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "collectionEnabled": {
            "description": "Automated collection is enabled.",
            "type": "boolean"
          },
          "consecutiveFailures": {
            "description": "Failed runs in a row, newest first.",
            "type": "integer"
          },
          "controlId": {
            "description": "Annex A control id.",
            "type": "string"
          },
          "freshness": {
            "description": "FRESH, STALE, FAILED or MANUAL_ONLY.",
            "type": "string"
          },
          "lastRunAt": {
            "description": "Start of the latest collection run (UTC), when any.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "lastRunStatus": {
            "description": "RUNNING, COMPLETED, FAILED, SKIPPED or UNKNOWN, when a run exists.",
            "type": "string"
          }
        },
        "required": [
          "controlId",
          "freshness",
          "consecutiveFailures",
          "collectionEnabled"
        ],
        "type": "object"
      },
      "ControlStateTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "exceptionCount": {
            "description": "Number of active exceptions.",
            "type": "integer"
          },
          "lastEvidenceAt": {
            "description": "Time of the latest evidence (UTC), when any.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "mttrMinutes": {
            "description": "Mean time to recover in minutes, when measured.",
            "nullable": true,
            "type": "integer"
          },
          "objectiveId": {
            "description": "Catalog control objective id.",
            "type": "string"
          },
          "state": {
            "description": "healthy, degraded, failed or unknown.",
            "type": "string"
          },
          "stateId": {
            "description": "Control reliability state id.",
            "type": "string"
          },
          "updatedAt": {
            "description": "Last update time (UTC); the sync field.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "stateId",
          "objectiveId",
          "state",
          "exceptionCount",
          "updatedAt"
        ],
        "type": "object"
      },
      "CursorMeta": {
        "additionalProperties": false,
        "description": "Metadata of a cursor-mode list response (the default when the request sends no offset parameter, or sends the cursor parameter).",
        "properties": {
          "hasMore": {
            "description": "True when another page exists.",
            "type": "boolean"
          },
          "limit": {
            "description": "Page size used.",
            "type": "integer"
          },
          "nextCursor": {
            "description": "Opaque cursor for the next page; null on the last page. Valid for 24 hours and bound to the token that received it.",
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "limit",
          "hasMore",
          "nextCursor"
        ],
        "type": "object"
      },
      "EmployeeTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "email": {
            "description": "Work e-mail. Every disclosure is audited (api.pii_read) and counts against the per-token PII window. Personal data: present only with pii:read.",
            "type": "string"
          },
          "employmentType": {
            "description": "Employment type, one of full_time, part_time, contractor, intern, temporary, employee, consultant, freelance, vendor, seasonal; null when unset or when the directory value is not one of these.",
            "nullable": true,
            "type": "string"
          },
          "hireDate": {
            "description": "Start date, when known.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "id": {
            "description": "Employee id (empl_ FlakeID); the keyset tie-break.",
            "type": "string"
          },
          "leaveDate": {
            "description": "End date, when known.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "managerId": {
            "description": "Manager (empl_ FlakeID), when set.",
            "nullable": true,
            "type": "string"
          },
          "name": {
            "description": "Full name. Every disclosure is audited (api.pii_read) and counts against the per-token PII window. Personal data: present only with pii:read.",
            "type": "string"
          },
          "status": {
            "description": "ACTIVE, ONBOARDING or TERMINATED (empty for legacy rows).",
            "type": "string"
          },
          "updatedAt": {
            "description": "Last write to the row (incremental-sync field); null until the row is backfilled.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          }
        },
        "required": [
          "id",
          "status",
          "employmentType",
          "hireDate",
          "leaveDate",
          "managerId",
          "updatedAt"
        ],
        "type": "object"
      },
      "EvidenceFreshnessTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "fresh": {
            "description": "Fresh items.",
            "type": "integer"
          },
          "score": {
            "description": "Sub-score (0-100).",
            "type": "integer"
          },
          "stale": {
            "description": "Stale items.",
            "type": "integer"
          },
          "total": {
            "description": "Evidence items.",
            "type": "integer"
          }
        },
        "required": [
          "score",
          "total",
          "fresh",
          "stale"
        ],
        "type": "object"
      },
      "EvidenceTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "collectedAt": {
            "description": "Collection time (UTC).",
            "format": "date-time",
            "type": "string"
          },
          "controlId": {
            "description": "Primary Annex A control id.",
            "type": "string"
          },
          "createdAt": {
            "description": "Creation time (UTC); the sync field (append-only, G-16).",
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "description": "Evidence id (ev_).",
            "type": "string"
          },
          "payloadType": {
            "description": "json, screenshot, pdf or text.",
            "type": "string"
          },
          "sourceType": {
            "description": "Collection source, for example aws, okta, manual.",
            "type": "string"
          },
          "stale": {
            "description": "The evidence is older than the control's maximum age.",
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "controlId",
          "sourceType",
          "payloadType",
          "stale",
          "collectedAt",
          "createdAt"
        ],
        "type": "object"
      },
      "GapComplianceTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "compliant": {
            "description": "Compliant controls.",
            "type": "integer"
          },
          "framework": {
            "description": "iso27001 or UNKNOWN.",
            "type": "string"
          },
          "missing": {
            "description": "Missing controls.",
            "type": "integer"
          },
          "na": {
            "description": "Not applicable controls.",
            "type": "integer"
          },
          "partial": {
            "description": "Partially compliant controls.",
            "type": "integer"
          },
          "score": {
            "description": "Sub-score (0-100).",
            "type": "integer"
          },
          "totalControls": {
            "description": "Controls assessed.",
            "type": "integer"
          }
        },
        "required": [
          "framework",
          "score",
          "totalControls",
          "compliant",
          "partial",
          "missing",
          "na"
        ],
        "type": "object"
      },
      "GapControlTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "controlId": {
            "description": "Annex A control id, for example A.5.1.",
            "type": "string"
          },
          "gapCount": {
            "description": "Number of open gaps.",
            "type": "integer"
          },
          "isBlocking": {
            "description": "At least one blocking gap.",
            "type": "boolean"
          },
          "lastAssessedAt": {
            "description": "Last scan time (UTC), when scanned.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "status": {
            "description": "COMPLIANT, PARTIAL, MISSING, NA or UNKNOWN.",
            "type": "string"
          },
          "updatedAt": {
            "description": "Last update time (UTC).",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "controlId",
          "status",
          "isBlocking",
          "gapCount",
          "updatedAt"
        ],
        "type": "object"
      },
      "ISOProjectTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "createdAt": {
            "description": "Creation time (UTC).",
            "format": "date-time",
            "type": "string"
          },
          "id": {
            "description": "ISO project id (iso_).",
            "type": "string"
          },
          "readinessScore": {
            "description": "Last stored readiness score (0-100).",
            "type": "integer"
          },
          "stage1Date": {
            "description": "Stage 1 audit date (UTC), when set.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "stage2Date": {
            "description": "Stage 2 audit date (UTC), when set.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "standard": {
            "description": "Standard and edition, for example ISO27001:2022.",
            "type": "string"
          },
          "status": {
            "description": "ACTIVE, CERTIFIED, SURVEILLANCE, ARCHIVED or UNKNOWN.",
            "type": "string"
          },
          "targetCertDate": {
            "description": "Target certification date (UTC), when set.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "updatedAt": {
            "description": "Last update time (UTC).",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "standard",
          "status",
          "readinessScore",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "MonitorSummaryTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "failed": {
            "description": "FAILED controls.",
            "type": "integer"
          },
          "fresh": {
            "description": "FRESH controls.",
            "type": "integer"
          },
          "manualOnly": {
            "description": "MANUAL_ONLY controls.",
            "type": "integer"
          },
          "stale": {
            "description": "STALE controls.",
            "type": "integer"
          },
          "total": {
            "description": "Controls.",
            "type": "integer"
          }
        },
        "required": [
          "total",
          "fresh",
          "stale",
          "failed",
          "manualOnly"
        ],
        "type": "object"
      },
      "MonitoringStatusTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "controls": {
            "description": "One entry per gap control of the project.",
            "items": {
              "$ref": "#/components/schemas/ControlMonitorTokenDTO"
            },
            "type": "array"
          },
          "projectId": {
            "description": "ISO project id (iso_).",
            "type": "string"
          },
          "summary": {
            "allOf": [
              {
                "$ref": "#/components/schemas/MonitorSummaryTokenDTO"
              }
            ],
            "description": "Counts per freshness class."
          }
        },
        "required": [
          "projectId",
          "controls",
          "summary"
        ],
        "type": "object"
      },
      "OffsetMeta": {
        "additionalProperties": false,
        "description": "Metadata of an offset-mode list response.",
        "properties": {
          "limit": {
            "description": "Page size used.",
            "type": "integer"
          },
          "offset": {
            "description": "Rows skipped.",
            "type": "integer"
          },
          "total": {
            "description": "Number of rows matching the filter in this organisation; approximate where the route says so.",
            "type": "integer"
          }
        },
        "required": [
          "total",
          "limit",
          "offset"
        ],
        "type": "object"
      },
      "OverviewDimensionsDTO": {
        "additionalProperties": false,
        "properties": {
          "evidenceFreshness": {
            "allOf": [
              {
                "$ref": "#/components/schemas/EvidenceFreshnessTokenDTO"
              }
            ],
            "description": "Evidence freshness."
          },
          "gapCompliance": {
            "description": "Gap compliance per framework.",
            "items": {
              "$ref": "#/components/schemas/GapComplianceTokenDTO"
            },
            "type": "array"
          },
          "riskExposure": {
            "allOf": [
              {
                "$ref": "#/components/schemas/RiskExposureTokenDTO"
              }
            ],
            "description": "Residual risk exposure."
          },
          "supplierPosture": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SupplierPostureTokenDTO"
              }
            ],
            "description": "Supplier posture."
          },
          "vulnFindingPosture": {
            "allOf": [
              {
                "$ref": "#/components/schemas/VulnFindingTokenDTO"
              }
            ],
            "description": "Supply-chain vulnerability posture, when the plan has it and findings are open.",
            "nullable": true
          }
        },
        "required": [
          "gapCompliance",
          "evidenceFreshness",
          "riskExposure",
          "supplierPosture"
        ],
        "type": "object"
      },
      "OverviewTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "dimensions": {
            "allOf": [
              {
                "$ref": "#/components/schemas/OverviewDimensionsDTO"
              }
            ],
            "description": "Per-dimension scores and counts."
          },
          "generatedAt": {
            "description": "Computation time (UTC).",
            "format": "date-time",
            "type": "string"
          },
          "overallScore": {
            "description": "Unified posture score (0-100).",
            "type": "integer"
          },
          "trend": {
            "description": "Daily posture snapshots, oldest first.",
            "items": {
              "$ref": "#/components/schemas/OverviewTrendPointDTO"
            },
            "type": "array"
          }
        },
        "required": [
          "overallScore",
          "dimensions",
          "trend",
          "generatedAt"
        ],
        "type": "object"
      },
      "OverviewTrendPointDTO": {
        "additionalProperties": false,
        "properties": {
          "date": {
            "description": "Snapshot date (YYYY-MM-DD, UTC).",
            "type": "string"
          },
          "score": {
            "description": "Posture score that day.",
            "type": "integer"
          }
        },
        "required": [
          "date",
          "score"
        ],
        "type": "object"
      },
      "PolicyTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "ackDone": {
            "description": "Acknowledgements received.",
            "type": "integer"
          },
          "ackTotal": {
            "description": "Acknowledgement requests sent.",
            "type": "integer"
          },
          "id": {
            "description": "Policy id (pol_).",
            "type": "string"
          },
          "policyType": {
            "description": "INFO_SECURITY, ACCESS_CONTROL, INCIDENT_RESPONSE, ACCEPTABLE_USE, DATA_CLASSIFICATION, SUPPLIER_SECURITY, BUSINESS_CONTINUITY, CHANGE_MANAGEMENT or UNKNOWN.",
            "type": "string"
          },
          "publishedAt": {
            "description": "Publication time (UTC), when published.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "status": {
            "description": "DRAFT, NEEDS_INPUT, READY, PUBLISHED or UNKNOWN.",
            "type": "string"
          },
          "updatedAt": {
            "description": "Last update time (UTC).",
            "format": "date-time",
            "type": "string"
          },
          "version": {
            "description": "Current version number.",
            "type": "integer"
          }
        },
        "required": [
          "id",
          "policyType",
          "status",
          "version",
          "ackTotal",
          "ackDone",
          "updatedAt"
        ],
        "type": "object"
      },
      "ReadinessCodeCount": {
        "additionalProperties": false,
        "properties": {
          "code": {
            "description": "SCOPE_NOT_SIGNED, SOA_NOT_SIGNED, CONTROL_MISSING_EVIDENCE, CONTROL_EVIDENCE_STALE, OPEN_NONCONFORMITIES, POLICY_ACK_RATE_LOW or ACCESS_REVIEW_OVERDUE.",
            "type": "string"
          },
          "count": {
            "description": "Number of occurrences.",
            "type": "integer"
          }
        },
        "required": [
          "code",
          "count"
        ],
        "type": "object"
      },
      "ReadinessTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "blockers": {
            "description": "Blocker codes and counts, sorted by code.",
            "items": {
              "$ref": "#/components/schemas/ReadinessCodeCount"
            },
            "type": "array"
          },
          "computedAt": {
            "description": "Computation time (UTC, RFC 3339).",
            "format": "date-time",
            "type": "string"
          },
          "projectId": {
            "description": "ISO project id (iso_).",
            "type": "string"
          },
          "projectStatus": {
            "description": "ACTIVE, CERTIFIED, SURVEILLANCE, ARCHIVED or UNKNOWN.",
            "type": "string"
          },
          "score": {
            "description": "Readiness score (0-100) computed now.",
            "type": "integer"
          },
          "warnings": {
            "description": "Warning codes and counts, sorted by code.",
            "items": {
              "$ref": "#/components/schemas/ReadinessCodeCount"
            },
            "type": "array"
          }
        },
        "required": [
          "projectId",
          "score",
          "projectStatus",
          "blockers",
          "warnings",
          "computedAt"
        ],
        "type": "object"
      },
      "RiskExposureTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "activeHigh": {
            "description": "Active high risks.",
            "type": "integer"
          },
          "activeMedium": {
            "description": "Active medium risks.",
            "type": "integer"
          },
          "mitigated": {
            "description": "Mitigated risks.",
            "type": "integer"
          },
          "score": {
            "description": "Sub-score (0-100).",
            "type": "integer"
          },
          "totalRecords": {
            "description": "Risk records.",
            "type": "integer"
          }
        },
        "required": [
          "score",
          "totalRecords",
          "activeHigh",
          "activeMedium",
          "mitigated"
        ],
        "type": "object"
      },
      "RiskRecordTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "assetIds": {
            "description": "Linked asset ids (ast_).",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "businessOwnerId": {
            "description": "Business owner employee id (empl_), when set.",
            "type": "string"
          },
          "controlIds": {
            "description": "Linked ISO 27001 control ids.",
            "items": {
              "type": "string"
            },
            "type": "array"
          },
          "createdAt": {
            "description": "Creation time (UTC).",
            "format": "date-time",
            "type": "string"
          },
          "domain": {
            "description": "Risk domain: access, compliance, vulnerability, resilience or assets.",
            "type": "string"
          },
          "dueAt": {
            "description": "Next review date (UTC), when set.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "id": {
            "description": "Risk record id (rrec_).",
            "type": "string"
          },
          "inherentScore": {
            "description": "Inherent risk score, when assessed.",
            "nullable": true,
            "type": "number"
          },
          "ownerId": {
            "description": "Risk owner employee id (empl_), when set.",
            "type": "string"
          },
          "residualScore": {
            "description": "Residual risk score, when assessed.",
            "nullable": true,
            "type": "number"
          },
          "status": {
            "description": "awaiting_review, active, accepted, mitigated, avoided or closed.",
            "type": "string"
          },
          "strategy": {
            "description": "Selected treatment strategy: accept, minimize or avoid.",
            "type": "string"
          },
          "supplierId": {
            "description": "Linked supplier id (sup_), when set.",
            "type": "string"
          },
          "technicalOwnerId": {
            "description": "Technical owner employee id (empl_), when set.",
            "type": "string"
          },
          "updatedAt": {
            "description": "Last modification time (UTC); the incremental-sync field.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "status",
          "assetIds",
          "controlIds",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "RoadmapTaskTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "assignedToId": {
            "description": "Assignee id (empl_ or usr_), only when the assignee is an id.",
            "type": "string"
          },
          "completedAt": {
            "description": "Completion time (UTC), when done.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "controlId": {
            "description": "Annex A control id.",
            "type": "string"
          },
          "createdAt": {
            "description": "Creation time (UTC).",
            "format": "date-time",
            "type": "string"
          },
          "dueAt": {
            "description": "Due date (UTC), when set.",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "id": {
            "description": "Roadmap task id (task_).",
            "type": "string"
          },
          "priority": {
            "description": "BLOCKING, HIGH, MEDIUM, LOW or UNKNOWN.",
            "type": "string"
          },
          "status": {
            "description": "OPEN, IN_PROGRESS, DONE, WONT_FIX or UNKNOWN.",
            "type": "string"
          },
          "updatedAt": {
            "description": "Last update time (UTC).",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "controlId",
          "status",
          "priority",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "SoAEntryTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "aiFlag": {
            "description": "The AI review flagged the entry for attention.",
            "type": "boolean"
          },
          "applicable": {
            "description": "The control is applicable to the ISMS scope.",
            "type": "boolean"
          },
          "controlId": {
            "description": "Annex A control id.",
            "type": "string"
          },
          "implementationStatus": {
            "description": "DRAFT, REVIEW, APPROVED or UNKNOWN.",
            "type": "string"
          },
          "updatedAt": {
            "description": "Last update time (UTC).",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "controlId",
          "applicable",
          "implementationStatus",
          "aiFlag",
          "updatedAt"
        ],
        "type": "object"
      },
      "SupplierPostureTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "agreementExpiring": {
            "description": "Agreements expiring soon.",
            "type": "integer"
          },
          "compliant": {
            "description": "Compliant suppliers.",
            "type": "integer"
          },
          "criticalMissingAssessment": {
            "description": "Critical suppliers without a completed assessment.",
            "type": "integer"
          },
          "reviewOverdue": {
            "description": "Suppliers with an overdue review.",
            "type": "integer"
          },
          "score": {
            "description": "Sub-score (0-100).",
            "type": "integer"
          },
          "totalSuppliers": {
            "description": "Suppliers.",
            "type": "integer"
          }
        },
        "required": [
          "score",
          "totalSuppliers",
          "compliant",
          "reviewOverdue",
          "agreementExpiring",
          "criticalMissingAssessment"
        ],
        "type": "object"
      },
      "SupplierTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "assessmentStatus": {
            "description": "Assessment status.",
            "type": "string"
          },
          "businessOwnerId": {
            "description": "Business owner employee id (empl_).",
            "type": "string"
          },
          "createdAt": {
            "description": "Creation time (UTC).",
            "format": "date-time",
            "type": "string"
          },
          "criticality": {
            "description": "Criticality.",
            "type": "string"
          },
          "dependencyType": {
            "description": "Dependency type, when set.",
            "type": "string"
          },
          "displayName": {
            "description": "Display name of the supplier.",
            "type": "string"
          },
          "hasCardData": {
            "description": "Processes card data.",
            "type": "boolean"
          },
          "hasPhi": {
            "description": "Processes health data.",
            "type": "boolean"
          },
          "hasPii": {
            "description": "Processes personal data.",
            "type": "boolean"
          },
          "id": {
            "description": "Supplier id (sup_).",
            "type": "string"
          },
          "lastAssessmentAt": {
            "description": "Last assessment time (UTC).",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "legalName": {
            "description": "Legal name of the supplier (an organisation).",
            "type": "string"
          },
          "networkAccessLevel": {
            "description": "Network access level, when set.",
            "type": "string"
          },
          "nextAssessmentDueAt": {
            "description": "Next assessment due (UTC).",
            "format": "date-time",
            "nullable": true,
            "type": "string"
          },
          "openFindingCount": {
            "description": "Open findings.",
            "type": "integer"
          },
          "openRiskCount": {
            "description": "Open risks.",
            "type": "integer"
          },
          "privilegedAccess": {
            "description": "Has privileged access.",
            "type": "boolean"
          },
          "securityOwnerId": {
            "description": "Security owner employee id (empl_).",
            "type": "string"
          },
          "serviceCategory": {
            "description": "Service category.",
            "type": "string"
          },
          "status": {
            "description": "Lifecycle status.",
            "type": "string"
          },
          "supplierOwnerId": {
            "description": "Supplier owner employee id (empl_).",
            "type": "string"
          },
          "supportsCrownJewel": {
            "description": "Supports a crown-jewel asset.",
            "type": "boolean"
          },
          "updatedAt": {
            "description": "Last update time (UTC).",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "legalName",
          "displayName",
          "serviceCategory",
          "criticality",
          "status",
          "assessmentStatus",
          "supportsCrownJewel",
          "hasPii",
          "hasPhi",
          "hasCardData",
          "privilegedAccess",
          "openRiskCount",
          "openFindingCount",
          "createdAt",
          "updatedAt"
        ],
        "type": "object"
      },
      "TokenErrorCode": {
        "description": "Stable error codes of the token API. Match on the code, never on the message.",
        "enum": [
          "AUDIT_UNAVAILABLE",
          "BILLING_UNAVAILABLE",
          "CONFLICT",
          "EXPIRY_REQUIRED",
          "EXPIRY_TOO_LONG",
          "FEATURE_GATED",
          "FORBIDDEN",
          "INSUFFICIENT_ROLE",
          "INSUFFICIENT_SCOPE",
          "INTERNAL_ERROR",
          "INVALID_CURSOR",
          "INVALID_TOKEN",
          "NOT_FOUND",
          "ORG_SUSPENDED",
          "OWNER_REQUIRED",
          "PII_UNAVAILABLE",
          "QUERY_TOO_BROAD",
          "RATE_LIMITED",
          "SCOPE_INVALID",
          "SUPPORT_SESSION_NO_MINT",
          "UNAUTHORIZED",
          "VALIDATION_FAILED"
        ],
        "type": "string"
      },
      "VerifyTokenAccepted": {
        "additionalProperties": false,
        "properties": {
          "acceptanceSeq": {
            "description": "Sequence number of the acceptance entry in the chain.",
            "format": "int64",
            "type": "integer"
          },
          "approvedAt": {
            "description": "When the exception was approved (RFC 3339).",
            "type": "string"
          },
          "breakClass": {
            "description": "manual or concurrent_append.",
            "type": "string"
          },
          "exceptionId": {
            "description": "Id of the approved exception.",
            "type": "string"
          },
          "seqNum": {
            "description": "Sequence number of the excused entry.",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "seqNum",
          "exceptionId",
          "approvedAt",
          "acceptanceSeq"
        ],
        "type": "object"
      },
      "VerifyTokenBreak": {
        "additionalProperties": false,
        "properties": {
          "detail": {
            "description": "Fixed description of the break kind at this sequence number; never contains hashes.",
            "type": "string"
          },
          "kind": {
            "description": "prev_link_mismatch, hash_mismatch, duplicate_seq, corrupt, seq_gap, gap_unaccounted, exception_unused, exception_invalid, exception_missing or exception_superseded.",
            "type": "string"
          },
          "seqNum": {
            "description": "Sequence number of the entry.",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "seqNum",
          "kind",
          "detail"
        ],
        "type": "object"
      },
      "VerifyTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "acceptedBreakCount": {
            "description": "Breaks excused by an approved exception.",
            "format": "int64",
            "type": "integer"
          },
          "acceptedBreaks": {
            "description": "Accepted breaks, at most 200.",
            "items": {
              "$ref": "#/components/schemas/VerifyTokenAccepted"
            },
            "type": "array"
          },
          "breakCount": {
            "description": "Total chain breaks found.",
            "format": "int64",
            "type": "integer"
          },
          "breaks": {
            "description": "Chain breaks, at most 200.",
            "items": {
              "$ref": "#/components/schemas/VerifyTokenBreak"
            },
            "type": "array"
          },
          "breaksTruncated": {
            "description": "True when breaks lists only the first 200.",
            "type": "boolean"
          },
          "brokenAt": {
            "description": "Sequence number of the first break, when there is one.",
            "format": "int64",
            "nullable": true,
            "type": "integer"
          },
          "chainedEntries": {
            "description": "Chained entries scanned.",
            "format": "int64",
            "type": "integer"
          },
          "effectiveBoundarySeq": {
            "description": "Sequence number from which strict verification applies.",
            "format": "int64",
            "nullable": true,
            "type": "integer"
          },
          "exceptionBoundarySeq": {
            "description": "Highest sequence number covered by exception markers.",
            "format": "int64",
            "nullable": true,
            "type": "integer"
          },
          "firstChainedSeq": {
            "description": "Sequence number of the first scanned chained entry.",
            "format": "int64",
            "nullable": true,
            "type": "integer"
          },
          "legacyEntries": {
            "description": "Entries that predate the hash chain.",
            "format": "int64",
            "type": "integer"
          },
          "pendingEntries": {
            "description": "Entries recorded but not yet chained.",
            "format": "int64",
            "type": "integer"
          },
          "protocolV2Seq": {
            "description": "Sequence number where the current chain protocol starts.",
            "format": "int64",
            "nullable": true,
            "type": "integer"
          },
          "scanComplete": {
            "description": "False when the scan ran out of time budget; valid is then false and the counts are partial.",
            "type": "boolean"
          },
          "seqGapCount": {
            "description": "Jumps in the sequence numbering.",
            "format": "int64",
            "type": "integer"
          },
          "seqGaps": {
            "description": "Sequence jumps, at most 200.",
            "items": {
              "$ref": "#/components/schemas/VerifyTokenSeqGap"
            },
            "type": "array"
          },
          "totalEntries": {
            "description": "Entries in the audit trail.",
            "format": "int64",
            "type": "integer"
          },
          "valid": {
            "description": "True when the scan completed and found no unaccepted break.",
            "type": "boolean"
          },
          "verifiedAt": {
            "description": "When the scan finished (UTC). Results are cached for 60 seconds per organization.",
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "valid",
          "scanComplete",
          "verifiedAt",
          "totalEntries",
          "legacyEntries",
          "chainedEntries",
          "pendingEntries",
          "breakCount",
          "breaksTruncated",
          "breaks",
          "acceptedBreakCount",
          "acceptedBreaks",
          "seqGapCount",
          "seqGaps"
        ],
        "type": "object"
      },
      "VerifyTokenSeqGap": {
        "additionalProperties": false,
        "properties": {
          "after": {
            "description": "Last sequence number before the jump.",
            "format": "int64",
            "type": "integer"
          },
          "next": {
            "description": "First sequence number after the jump.",
            "format": "int64",
            "type": "integer"
          }
        },
        "required": [
          "after",
          "next"
        ],
        "type": "object"
      },
      "VulnFindingTokenDTO": {
        "additionalProperties": false,
        "properties": {
          "critical": {
            "description": "Open critical findings.",
            "type": "integer"
          },
          "high": {
            "description": "Open high findings.",
            "type": "integer"
          },
          "low": {
            "description": "Open low findings.",
            "type": "integer"
          },
          "medium": {
            "description": "Open medium findings.",
            "type": "integer"
          },
          "score": {
            "description": "Sub-score (0-100).",
            "type": "integer"
          },
          "totalOpen": {
            "description": "Open findings.",
            "type": "integer"
          }
        },
        "required": [
          "score",
          "totalOpen",
          "critical",
          "high",
          "medium",
          "low"
        ],
        "type": "object"
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid query parameter. code VALIDATION_FAILED; args.parameter names the parameter, args.reason the rule, args.allowed the permitted values of an enum.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "examples": {
              "invalidEnum": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ab12c",
                    "code": "VALIDATION_FAILED",
                    "message": "invalid query parameter",
                    "args": {
                      "parameter": "filter[status][eq]",
                      "reason": "value not allowed",
                      "allowed": [
                        "OPEN",
                        "IN_PROGRESS",
                        "COMPLETED",
                        "CANCELLED"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing (UNAUTHORIZED) or invalid, expired or revoked (INVALID_TOKEN) token.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "examples": {
              "invalidToken": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ab12c",
                    "code": "INVALID_TOKEN",
                    "message": "invalid or expired API token"
                  }
                }
              }
            }
          }
        }
      },
      "FeatureGated": {
        "description": "The tenant plan does not include lifecycle workflows. code FEATURE_GATED; args.feature, args.minTier, args.minTierName.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "examples": {
              "gated": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ab12c",
                    "code": "FEATURE_GATED",
                    "message": "This feature requires Growth or higher.",
                    "args": {
                      "feature": "lifecycle_workflows",
                      "minTier": "growth",
                      "minTierName": "Growth"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "The token lacks the jml:read scope (INSUFFICIENT_SCOPE; a token holding pii:read alone reaches no endpoint here), or the request is refused (FORBIDDEN). A token holding pii:read is also refused with INSUFFICIENT_SCOPE when personal data cannot be disclosed to it (personal-data disclosure is disabled for the tenant, or the token has no creator); it is never silently downgraded to the masked shape.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "examples": {
              "scope": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ab12c",
                    "code": "INSUFFICIENT_SCOPE",
                    "message": "token lacks the required scope"
                  }
                }
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Unknown, foreign-tenant, wrong-type or malformed case id. Always the same body.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "examples": {
              "notFound": {
                "value": {
                  "data": null,
                  "error": {
                    "code": "NOT_FOUND",
                    "message": "resource not found"
                  },
                  "meta": {}
                }
              }
            }
          }
        }
      },
      "QueryTooBroad": {
        "description": "The filtered feed exceeds the server limit and is never truncated. code QUERY_TOO_BROAD; narrow by date range, caseStatus or employeeId.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "examples": {
              "tooBroad": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ab12c",
                    "code": "QUERY_TOO_BROAD",
                    "message": "the query matches too many items; narrow the date range or filter by caseStatus or employeeId"
                  }
                }
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded. code RATE_LIMITED; wait Retry-After seconds. Applies to the personal-data (pii:read) request window on case endpoints, where Retry-After is the time until the window ends. That window is shared by all calls of the token, over REST and MCP; a request that fails with 503 AUDIT_UNAVAILABLE is not refunded, so retrying spends more of it. Do not build a design that depends on an exact number of requests. It also applies to concurrent feed requests on the items feeds, where Retry-After is 1. The body carries no meta.",
        "headers": {
          "Retry-After": {
            "description": "Whole seconds to wait before retrying: the time until the personal-data window ends, or 1 for the items feeds.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "examples": {
              "limited": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ab12c",
                    "code": "RATE_LIMITED",
                    "message": "rate limit exceeded, retry after the time given in the Retry-After header"
                  }
                }
              }
            }
          }
        }
      },
      "InternalError": {
        "description": "Unexpected server error. code INTERNAL_ERROR; quote error.id to support.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "examples": {
              "internal": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ab12c",
                    "code": "INTERNAL_ERROR",
                    "message": "internal error"
                  }
                }
              }
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "A dependency is temporarily unavailable (BILLING_UNAVAILABLE), or a response containing name or email could not be audited and was withheld (AUDIT_UNAVAILABLE). Retry later.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "examples": {
              "billing": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ab12c",
                    "code": "BILLING_UNAVAILABLE",
                    "message": "billing service temporarily unavailable"
                  }
                }
              }
            }
          }
        }
      },
      "UploadBadRequest": {
        "description": "The upload was rejected. code INVALID_REQUEST (unreadable multipart body), MISSING_FILE (no file field), UNSUPPORTED_FORMAT (filename is not a supported manifest) or PARSE_ERROR (the manifest could not be parsed).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SscsErrorEnvelope"
            },
            "examples": {
              "unsupported": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EW6Y4HF",
                    "code": "UNSUPPORTED_FORMAT",
                    "message": "unsupported manifest: Gemfile.lock. supports: go.sum, pom.xml, build.gradle/.kts, package.json, requirements.txt"
                  }
                }
              },
              "missingFile": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EZ1X8GD",
                    "code": "MISSING_FILE",
                    "message": "multipart field 'file' is required"
                  }
                }
              }
            }
          }
        }
      },
      "FindingsBadRequest": {
        "description": "Unrecognised query value. code INVALID_STATUS or INVALID_SEVERITY.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SscsErrorEnvelope"
            },
            "examples": {
              "status": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EX4S2LP",
                    "code": "INVALID_STATUS",
                    "message": "invalid status value: closed"
                  }
                }
              }
            }
          }
        }
      },
      "FindingStatusBadRequest": {
        "description": "The body is invalid. code VALIDATION_FAILED (schema violation) or INVALID_STATUS.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SscsErrorEnvelope"
            },
            "examples": {
              "schema": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EC3F7RD",
                    "code": "VALIDATION_FAILED",
                    "message": "request validation failed: status is required"
                  }
                }
              }
            }
          }
        }
      },
      "SbomNotFound": {
        "description": "Unknown or foreign-tenant SBOM id. code NOT_FOUND.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SscsErrorEnvelope"
            },
            "examples": {
              "notFound": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EH8T6RC",
                    "code": "NOT_FOUND",
                    "message": "sbom not found"
                  }
                }
              }
            }
          }
        }
      },
      "PayloadTooLarge": {
        "description": "The body exceeds the size limit. code FILE_TOO_LARGE (upload, 5 MB) or PAYLOAD_TOO_LARGE (JSON body).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SscsErrorEnvelope"
            },
            "examples": {
              "tooLarge": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EN7B3QJ",
                    "code": "FILE_TOO_LARGE",
                    "message": "file exceeds 5 MB limit"
                  }
                }
              }
            }
          }
        }
      },
      "SscsBadRequest": {
        "description": "The JSON body does not match the request schema. code VALIDATION_FAILED, or INVALID_REQUEST when the body cannot be read.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SscsErrorEnvelope"
            },
            "examples": {
              "validation": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EP5R2WK",
                    "code": "VALIDATION_FAILED",
                    "message": "request validation failed: name is required"
                  }
                }
              }
            }
          }
        }
      },
      "SscsUnauthorized": {
        "description": "Missing (UNAUTHORIZED) or invalid, expired or revoked (INVALID_TOKEN) token.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SscsErrorEnvelope"
            },
            "examples": {
              "invalidToken": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EK4N2QX",
                    "code": "INVALID_TOKEN",
                    "message": "invalid or expired API token"
                  }
                }
              }
            }
          }
        }
      },
      "SscsFeatureGated": {
        "description": "The tenant plan does not include supply chain security. code FEATURE_GATED; args.feature, args.minTier, args.minTierName.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SscsErrorEnvelope"
            },
            "examples": {
              "gated": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EQ2W9LD",
                    "code": "FEATURE_GATED",
                    "message": "This feature requires Growth or higher.",
                    "args": {
                      "feature": "supply_chain_security",
                      "minTier": "growth",
                      "minTierName": "Growth"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "SscsForbidden": {
        "description": "The token lacks the required scope (INSUFFICIENT_SCOPE) or the request is refused (FORBIDDEN).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SscsErrorEnvelope"
            },
            "examples": {
              "scope": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EB7M3PA",
                    "code": "INSUFFICIENT_SCOPE",
                    "message": "this API token does not have the required scope: sbom:write"
                  }
                }
              }
            }
          }
        }
      },
      "SscsRateLimited": {
        "description": "Too many failed authentication attempts from this address. code RATE_LIMITED; wait Retry-After seconds.",
        "headers": {
          "Retry-After": {
            "description": "Whole seconds to wait before retrying.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SscsErrorEnvelope"
            },
            "examples": {
              "limited": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ER9L5TY",
                    "code": "RATE_LIMITED",
                    "message": "rate limit exceeded, retry after the time given in the Retry-After header"
                  }
                }
              }
            }
          }
        }
      },
      "SscsInternalError": {
        "description": "Unexpected server error. code DB_ERROR (or VALIDATION_ERROR when the request could not be validated); quote error.id to support.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SscsErrorEnvelope"
            },
            "examples": {
              "internal": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EJ6D1MV",
                    "code": "DB_ERROR",
                    "message": "internal server error"
                  }
                }
              }
            }
          }
        }
      },
      "SscsServiceUnavailable": {
        "description": "Billing is temporarily unavailable, so the plan could not be checked. code BILLING_UNAVAILABLE. Retry later.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SscsErrorEnvelope"
            },
            "examples": {
              "billing": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EU3V8NZ",
                    "code": "BILLING_UNAVAILABLE",
                    "message": "billing service temporarily unavailable"
                  }
                }
              }
            }
          }
        }
      },
      "BadQuery": {
        "description": "Unknown or malformed query parameter. code VALIDATION_FAILED.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "query": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EQ8T3LC",
                    "code": "VALIDATION_FAILED",
                    "message": "invalid query parameter"
                  }
                }
              }
            }
          }
        }
      },
      "BadVersion": {
        "description": "A version in the path is not an integer. code VALIDATION_FAILED.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "version": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EV2N6HD",
                    "code": "VALIDATION_FAILED",
                    "message": "version must be an integer"
                  }
                }
              }
            }
          }
        }
      },
      "ForbiddenWrite": {
        "description": "The token lacks supplier_template:write (INSUFFICIENT_SCOPE), has no accountable person (FORBIDDEN: this principal cannot edit questionnaires), or the target is the built-in questionnaire (BUILTIN_IMMUTABLE).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "scope": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EB8M4PB",
                    "code": "INSUFFICIENT_SCOPE",
                    "message": "this API token does not have the required scope: supplier_template:write"
                  }
                }
              }
            }
          }
        }
      },
      "TemplateNotFound": {
        "description": "Unknown or foreign-tenant questionnaire, version or clone source. code NOT_FOUND.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "notFound": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EH8T6RC",
                    "code": "NOT_FOUND",
                    "message": "template not found"
                  }
                }
              }
            }
          }
        }
      },
      "SectionNotFound": {
        "description": "Unknown questionnaire (NOT_FOUND) or unknown section in it (SECTION_NOT_FOUND).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "section": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EJ4S9WM",
                    "code": "SECTION_NOT_FOUND",
                    "message": "section not found"
                  }
                }
              }
            }
          }
        }
      },
      "TemplateLimitConflict": {
        "description": "The organization already holds 50 questionnaires. code TEMPLATE_LIMIT_REACHED.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "limit": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EL5K1TG",
                    "code": "TEMPLATE_LIMIT_REACHED",
                    "message": "the organization has reached its template limit"
                  }
                }
              }
            }
          }
        }
      },
      "DraftConflict": {
        "description": "Only a published version can be reopened (NOT_A_DRAFT), or the family already has an open draft (DRAFT_EXISTS).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "exists": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ED3F8NB",
                    "code": "DRAFT_EXISTS",
                    "message": "a draft is already open for this template family"
                  }
                }
              }
            }
          }
        }
      },
      "EditConflict": {
        "description": "The draft cannot take this edit. code STALE_REVISION (the draft changed since the revision sent; args.current holds the current document), or TEMPLATE_PUBLISHED, TEMPLATE_SUBMITTED or TEMPLATE_ARCHIVED (not a draft; args.current holds the document), or TEMPLATE_SIZE_LIMIT_REACHED.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "stale": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ES9R4YA",
                    "code": "STALE_REVISION",
                    "message": "the draft changed since you last read it"
                  }
                }
              }
            }
          }
        }
      },
      "SectionConflict": {
        "description": "Everything in EditConflict, plus SECTION_LIMIT_REACHED (20 sections), SECTION_REFERENCED (a question elsewhere depends on a question in this section; args.dependents lists them) and QUESTION_IS_GATING_TRIGGER (the section holds the vendor-type question).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "referenced": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EW6C2ZK",
                    "code": "SECTION_REFERENCED",
                    "message": "questions in other sections depend on questions in this section"
                  }
                }
              }
            }
          }
        }
      },
      "QuestionNotFound": {
        "description": "Unknown questionnaire (NOT_FOUND), question (QUESTION_NOT_FOUND) or option (OPTION_NOT_FOUND).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "e": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EK2Q7DN",
                    "code": "QUESTION_NOT_FOUND",
                    "message": "question not found"
                  }
                }
              }
            }
          }
        }
      },
      "ContentNotFound": {
        "description": "Unknown questionnaire, question or option in the path. code NOT_FOUND.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "e": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EK3R8EP",
                    "code": "NOT_FOUND",
                    "message": "question not found"
                  }
                }
              }
            }
          }
        }
      },
      "ContentConflict": {
        "description": "The version cannot take this edit. code TEMPLATE_PUBLISHED, TEMPLATE_SUBMITTED or TEMPLATE_ARCHIVED (not a draft; args.current holds the document).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "e": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EM4S9FQ",
                    "code": "TEMPLATE_SUBMITTED",
                    "message": "a submitted template's content cannot be edited until it is withdrawn or sent back"
                  }
                }
              }
            }
          }
        }
      },
      "QuestionAddConflict": {
        "description": "Everything in EditConflict, plus QUESTION_LIMIT_REACHED (50 questions in the section or 300 in the questionnaire).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "e": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EN5T1GR",
                    "code": "QUESTION_LIMIT_REACHED",
                    "message": "this section is at its question limit"
                  }
                }
              }
            }
          }
        }
      },
      "QuestionDeleteConflict": {
        "description": "Everything in EditConflict, plus QUESTION_REFERENCED (another question's gating rule depends on it; args.dependents lists them) and QUESTION_IS_GATING_TRIGGER (the vendor-type question cannot be deleted).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "e": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EP6U2HS",
                    "code": "QUESTION_REFERENCED",
                    "message": "another question's gating rule references this question"
                  }
                }
              }
            }
          }
        }
      },
      "OptionAddConflict": {
        "description": "Everything in EditConflict, plus OPTIONS_NOT_ALLOWED (the question is not a choice question) and OPTION_LIMIT_REACHED (12 options).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "e": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EQ7V3JT",
                    "code": "OPTION_LIMIT_REACHED",
                    "message": "this question is at its option limit"
                  }
                }
              }
            }
          }
        }
      },
      "OptionDeleteConflict": {
        "description": "Everything in EditConflict, plus OPTION_MINIMUM_REACHED (a choice question keeps two options) and OPTION_REFERENCED (another question's gating rule depends on the option; args.dependents lists them).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "e": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ER8W4KV",
                    "code": "OPTION_MINIMUM_REACHED",
                    "message": "a choice question needs at least two options"
                  }
                }
              }
            }
          }
        }
      },
      "SubmitConflict": {
        "description": "The version cannot be submitted. code STALE_REVISION (the draft changed since the revision sent), ALREADY_SUBMITTED, NOT_A_DRAFT (published) or TEMPLATE_ARCHIVED; args.current holds the document.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "e": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ES9X5LW",
                    "code": "ALREADY_SUBMITTED",
                    "message": "this draft has already been submitted for approval"
                  }
                }
              }
            }
          }
        }
      },
      "WithdrawConflict": {
        "description": "The version is not awaiting approval. code NOT_SUBMITTED (a draft), NOT_A_DRAFT (published) or TEMPLATE_ARCHIVED; args.current holds the document.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "e": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ET2Y6MX",
                    "code": "NOT_SUBMITTED",
                    "message": "this template is not awaiting approval"
                  }
                }
              }
            }
          }
        }
      },
      "TemplateInvalid": {
        "description": "The draft fails validation and was not submitted. code TEMPLATE_INVALID; args.violations lists the problems.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "e": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EU3Z7NY",
                    "code": "TEMPLATE_INVALID",
                    "message": "the draft fails validation and cannot be submitted"
                  }
                }
              }
            }
          }
        }
      },
      "RiskReductionNotAcknowledged": {
        "description": "The edit clears or lowers a critical finding severity without the acknowledgement only a person can give. code RISK_REDUCTION_NOT_ACKNOWLEDGED.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "e": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EV4A8PZ",
                    "code": "RISK_REDUCTION_NOT_ACKNOWLEDGED",
                    "message": "clearing or downgrading a critical finding severity must be acknowledged"
                  }
                }
              }
            }
          }
        }
      },
      "NothingToTranslate": {
        "description": "No source text in a language other than the target. code NOTHING_TO_TRANSLATE.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "e": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EW5B9QA",
                    "code": "NOTHING_TO_TRANSLATE",
                    "message": "no source text in another language"
                  }
                }
              }
            }
          }
        }
      },
      "TranslationFailed": {
        "description": "The AI provider failed or returned nothing. code AI_FAILED; retry later.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "e": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EX6C1RB",
                    "code": "AI_FAILED",
                    "message": "translation failed",
                    "try again": null
                  }
                }
              }
            }
          }
        }
      },
      "ServiceUnavailableTranslate": {
        "description": "Billing is temporarily unavailable (BILLING_UNAVAILABLE), or no translation provider is configured (AI_UNAVAILABLE). Retry later.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "e": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EY7D2SC",
                    "code": "AI_UNAVAILABLE",
                    "message": "translation is not available"
                  }
                }
              }
            }
          }
        }
      },
      "ForbiddenOptionPatch": {
        "description": "The token lacks supplier_template:write (INSUFFICIENT_SCOPE), has no accountable person (FORBIDDEN), the target is the built-in questionnaire (BUILTIN_IMMUTABLE), or the body sets acknowledgeRiskReduction to true, which only a person may do (HUMAN_APPROVAL_REQUIRED).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "human": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EZ8E3TD",
                    "code": "HUMAN_APPROVAL_REQUIRED",
                    "message": "this action requires a human principal and cannot be performed by an API token"
                  }
                }
              }
            }
          }
        }
      },
      "RateLimitedWrite": {
        "description": "Too many failed authentication attempts from this address, or the token used its hourly write budget (30 structural, 120 field edits). code RATE_LIMITED; wait Retry-After seconds, also in error.args.retryAfterSeconds.",
        "headers": {
          "Retry-After": {
            "description": "Whole seconds to wait before retrying.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "budget": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EM3X7PV",
                    "code": "RATE_LIMITED",
                    "message": "questionnaire rate limit exceeded",
                    "args": {
                      "retryAfterSeconds": 1800
                    }
                  }
                }
              }
            }
          }
        }
      },
      "SupplierTemplatesBadRequest": {
        "description": "The JSON body does not match the request schema, or the revision is missing where required. code VALIDATION_FAILED.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "validation": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EP5R2WK",
                    "code": "VALIDATION_FAILED",
                    "message": "request validation failed: name is required"
                  }
                }
              }
            }
          }
        }
      },
      "SupplierTemplatesUnauthorized": {
        "description": "Missing (UNAUTHORIZED) or invalid, expired or revoked (INVALID_TOKEN) token.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "invalidToken": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EK4N2QX",
                    "code": "INVALID_TOKEN",
                    "message": "invalid or expired API token"
                  }
                }
              }
            }
          }
        }
      },
      "SupplierTemplatesFeatureGated": {
        "description": "The tenant plan does not include supply chain security. code FEATURE_GATED; args.feature, args.minTier, args.minTierName.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "gated": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EQ2W9LD",
                    "code": "FEATURE_GATED",
                    "message": "This feature requires Growth or higher.",
                    "args": {
                      "feature": "supply_chain_security",
                      "minTier": "growth",
                      "minTierName": "Growth"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "SupplierTemplatesForbidden": {
        "description": "The token lacks the required scope (INSUFFICIENT_SCOPE), or the request is refused (FORBIDDEN, INSUFFICIENT_ROLE for a draft the caller may not read).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "scope": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EB7M3PA",
                    "code": "INSUFFICIENT_SCOPE",
                    "message": "this API token does not have the required scope: supplier_template:read"
                  }
                }
              }
            }
          }
        }
      },
      "SupplierTemplatesPayloadTooLarge": {
        "description": "The JSON body exceeds the size limit. code PAYLOAD_TOO_LARGE.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "tooLarge": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EN7B3QJ",
                    "code": "PAYLOAD_TOO_LARGE",
                    "message": "request body exceeds the maximum allowed size"
                  }
                }
              }
            }
          }
        }
      },
      "SupplierTemplatesRateLimited": {
        "description": "Too many failed authentication attempts from this address. code RATE_LIMITED; wait Retry-After seconds.",
        "headers": {
          "Retry-After": {
            "description": "Whole seconds to wait before retrying.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "limited": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ER9L5TY",
                    "code": "RATE_LIMITED",
                    "message": "rate limit exceeded, retry after the time given in the Retry-After header"
                  }
                }
              }
            }
          }
        }
      },
      "SupplierTemplatesInternalError": {
        "description": "Unexpected server error. code DB_ERROR; quote error.id to support.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "internal": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EJ6D1MV",
                    "code": "DB_ERROR",
                    "message": "internal server error"
                  }
                }
              }
            }
          }
        }
      },
      "SupplierTemplatesServiceUnavailable": {
        "description": "Billing is temporarily unavailable, so the plan could not be checked. code BILLING_UNAVAILABLE. Retry later.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/SupplierTemplatesErrorEnvelope"
            },
            "examples": {
              "billing": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EU3V8NZ",
                    "code": "BILLING_UNAVAILABLE",
                    "message": "billing service temporarily unavailable"
                  }
                }
              }
            }
          }
        }
      },
      "CreateForbidden": {
        "description": "Not allowed to create this token. FORBIDDEN (not an Owner or Manager, or an API token), SUPPORT_SESSION_NO_MINT (support session), OWNER_REQUIRED (the scope needs an Owner, for example pii:read), MEMBERSHIP_REQUIRED (an active membership of this organization is required) or INSUFFICIENT_ROLE (the caller role cannot grant the scope).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/TokensErrorEnvelope"
            },
            "examples": {
              "ownerRequired": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EL5W1QA",
                    "code": "OWNER_REQUIRED",
                    "message": "only an organisation owner can create a token with the pii:read scope"
                  }
                }
              }
            }
          }
        }
      },
      "CreateRejected": {
        "description": "The request is well-formed but cannot be granted. SCOPE_UNAVAILABLE (pii:read not enabled yet), INVALID_EXPIRY (expiresAt not in the future), EXPIRY_REQUIRED, EXPIRY_TOO_LONG or TOKEN_LIMIT_EXCEEDED (20 tokens per organization).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/TokensErrorEnvelope"
            },
            "examples": {
              "expiryRequired": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EV7N2CJ",
                    "code": "EXPIRY_REQUIRED",
                    "message": "a token with the jml:read scope must have an expiresAt"
                  }
                }
              },
              "limit": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EG3R9XT",
                    "code": "TOKEN_LIMIT_EXCEEDED",
                    "message": "maximum of 20 API tokens per organization"
                  }
                }
              }
            }
          }
        }
      },
      "TokensBadRequest": {
        "description": "The body does not match the request schema (VALIDATION_FAILED), cannot be read (INVALID_BODY) or names an unknown scope (SCOPE_INVALID).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/TokensErrorEnvelope"
            },
            "examples": {
              "validation": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ET4K8RB",
                    "code": "VALIDATION_FAILED",
                    "message": "request validation failed: scopes is required"
                  }
                }
              }
            }
          }
        }
      },
      "TokensUnauthorized": {
        "description": "No signed-in session. code UNAUTHORIZED.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/TokensErrorEnvelope"
            },
            "examples": {
              "unauthorized": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EH2P6VN",
                    "code": "UNAUTHORIZED",
                    "message": "unauthorized"
                  }
                }
              }
            }
          }
        }
      },
      "TokensForbidden": {
        "description": "The caller is not an Owner or Manager of the organization, or the request carries an API token (FORBIDDEN), or the session is a support session (SUPPORT_SESSION_NO_MINT on create and revoke).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/TokensErrorEnvelope"
            },
            "examples": {
              "forbidden": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EF9D3MS",
                    "code": "FORBIDDEN",
                    "message": "API tokens cannot manage other tokens"
                  }
                }
              }
            }
          }
        }
      },
      "TokensNotFound": {
        "description": "Unknown token id, or a token of another organization. code NOT_FOUND.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/TokensErrorEnvelope"
            },
            "examples": {
              "notFound": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EP8U4HY",
                    "code": "NOT_FOUND",
                    "message": "token not found"
                  }
                }
              }
            }
          }
        }
      },
      "TokensInternalError": {
        "description": "Unexpected server error. code DB_ERROR or TOKEN_GENERATION_FAILED; retry later and quote error.id if it persists.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/TokensErrorEnvelope"
            },
            "examples": {
              "db": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "EY6C1ZK",
                    "code": "DB_ERROR",
                    "message": "internal server error"
                  }
                }
              }
            }
          }
        }
      },
      "HealthRateLimited": {
        "description": "This client IP address sent too many health checks. code RATE_LIMITED; wait Retry-After seconds.",
        "headers": {
          "Retry-After": {
            "description": "Whole seconds to wait before retrying.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/HealthErrorEnvelope"
            },
            "examples": {
              "rateLimited": {
                "value": {
                  "data": null,
                  "error": {
                    "id": "ER3T7KD",
                    "code": "RATE_LIMITED",
                    "message": "Too many health checks. Retry after the interval in Retry-After."
                  }
                }
              }
            }
          }
        }
      },
      "Error400InvalidCursorValidationFailed": {
        "content": {
          "application/json": {
            "schema": {
              "additionalProperties": false,
              "properties": {
                "data": {
                  "additionalProperties": false,
                  "description": "Always null.",
                  "nullable": true,
                  "type": "object"
                },
                "error": {
                  "additionalProperties": false,
                  "properties": {
                    "args": {
                      "additionalProperties": {},
                      "description": "Structured details such as the rejected parameter.",
                      "type": "object"
                    },
                    "code": {
                      "enum": [
                        "INVALID_CURSOR",
                        "VALIDATION_FAILED"
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "Correlation id to quote to support.",
                      "type": "string"
                    },
                    "message": {
                      "description": "User-safe message.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "data",
                "error"
              ],
              "type": "object"
            }
          }
        },
        "description": "The request is invalid.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "x-retryable": false
      },
      "Error400ValidationFailed": {
        "content": {
          "application/json": {
            "schema": {
              "additionalProperties": false,
              "properties": {
                "data": {
                  "additionalProperties": false,
                  "description": "Always null.",
                  "nullable": true,
                  "type": "object"
                },
                "error": {
                  "additionalProperties": false,
                  "properties": {
                    "args": {
                      "additionalProperties": {},
                      "description": "Structured details such as the rejected parameter.",
                      "type": "object"
                    },
                    "code": {
                      "enum": [
                        "VALIDATION_FAILED"
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "Correlation id to quote to support.",
                      "type": "string"
                    },
                    "message": {
                      "description": "User-safe message.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "data",
                "error"
              ],
              "type": "object"
            }
          }
        },
        "description": "The request is invalid.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "x-retryable": false
      },
      "Error401InvalidTokenUnauthorized": {
        "content": {
          "application/json": {
            "schema": {
              "additionalProperties": false,
              "properties": {
                "data": {
                  "additionalProperties": false,
                  "description": "Always null.",
                  "nullable": true,
                  "type": "object"
                },
                "error": {
                  "additionalProperties": false,
                  "properties": {
                    "args": {
                      "additionalProperties": {},
                      "description": "Structured details such as the rejected parameter.",
                      "type": "object"
                    },
                    "code": {
                      "enum": [
                        "INVALID_TOKEN",
                        "UNAUTHORIZED"
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "Correlation id to quote to support.",
                      "type": "string"
                    },
                    "message": {
                      "description": "User-safe message.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "data",
                "error"
              ],
              "type": "object"
            }
          }
        },
        "description": "The token is missing, malformed, expired or revoked.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "x-retryable": false
      },
      "Error402FeatureGated": {
        "content": {
          "application/json": {
            "schema": {
              "additionalProperties": false,
              "properties": {
                "data": {
                  "additionalProperties": false,
                  "description": "Always null.",
                  "nullable": true,
                  "type": "object"
                },
                "error": {
                  "additionalProperties": false,
                  "properties": {
                    "args": {
                      "additionalProperties": {},
                      "description": "Structured details such as the rejected parameter.",
                      "type": "object"
                    },
                    "code": {
                      "enum": [
                        "FEATURE_GATED"
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "Correlation id to quote to support.",
                      "type": "string"
                    },
                    "message": {
                      "description": "User-safe message.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "data",
                "error"
              ],
              "type": "object"
            }
          }
        },
        "description": "The organisation's plan does not include the feature this route needs.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "x-retryable": false
      },
      "Error403ForbiddenInsufficientScopeOrgSuspended": {
        "content": {
          "application/json": {
            "schema": {
              "additionalProperties": false,
              "properties": {
                "data": {
                  "additionalProperties": false,
                  "description": "Always null.",
                  "nullable": true,
                  "type": "object"
                },
                "error": {
                  "additionalProperties": false,
                  "properties": {
                    "args": {
                      "additionalProperties": {},
                      "description": "Structured details such as the rejected parameter.",
                      "type": "object"
                    },
                    "code": {
                      "enum": [
                        "FORBIDDEN",
                        "INSUFFICIENT_SCOPE",
                        "ORG_SUSPENDED"
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "Correlation id to quote to support.",
                      "type": "string"
                    },
                    "message": {
                      "description": "User-safe message.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "data",
                "error"
              ],
              "type": "object"
            }
          }
        },
        "description": "The token may not use this route.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "x-retryable": false
      },
      "Error403ForbiddenInsufficientScopeOrgSuspendedPiiUnavailable": {
        "content": {
          "application/json": {
            "schema": {
              "additionalProperties": false,
              "properties": {
                "data": {
                  "additionalProperties": false,
                  "description": "Always null.",
                  "nullable": true,
                  "type": "object"
                },
                "error": {
                  "additionalProperties": false,
                  "properties": {
                    "args": {
                      "additionalProperties": {},
                      "description": "Structured details such as the rejected parameter.",
                      "type": "object"
                    },
                    "code": {
                      "enum": [
                        "FORBIDDEN",
                        "INSUFFICIENT_SCOPE",
                        "ORG_SUSPENDED",
                        "PII_UNAVAILABLE"
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "Correlation id to quote to support.",
                      "type": "string"
                    },
                    "message": {
                      "description": "User-safe message.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "data",
                "error"
              ],
              "type": "object"
            }
          }
        },
        "description": "The token may not use this route.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "x-retryable": false
      },
      "Error404NotFound": {
        "content": {
          "application/json": {
            "schema": {
              "additionalProperties": false,
              "properties": {
                "data": {
                  "additionalProperties": false,
                  "description": "Always null.",
                  "nullable": true,
                  "type": "object"
                },
                "error": {
                  "additionalProperties": false,
                  "properties": {
                    "args": {
                      "additionalProperties": {},
                      "description": "Structured details such as the rejected parameter.",
                      "type": "object"
                    },
                    "code": {
                      "enum": [
                        "NOT_FOUND"
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "Correlation id to quote to support.",
                      "type": "string"
                    },
                    "message": {
                      "description": "User-safe message.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "data",
                "error"
              ],
              "type": "object"
            }
          }
        },
        "description": "The resource does not exist in this organisation.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "x-retryable": false
      },
      "Error422QueryTooBroad": {
        "content": {
          "application/json": {
            "schema": {
              "additionalProperties": false,
              "properties": {
                "data": {
                  "additionalProperties": false,
                  "description": "Always null.",
                  "nullable": true,
                  "type": "object"
                },
                "error": {
                  "additionalProperties": false,
                  "properties": {
                    "args": {
                      "additionalProperties": {},
                      "description": "Structured details such as the rejected parameter.",
                      "type": "object"
                    },
                    "code": {
                      "enum": [
                        "QUERY_TOO_BROAD"
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "Correlation id to quote to support.",
                      "type": "string"
                    },
                    "message": {
                      "description": "User-safe message.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "data",
                "error"
              ],
              "type": "object"
            }
          }
        },
        "description": "The result set is too large for one request.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "x-retryable": false
      },
      "Error429RateLimited": {
        "content": {
          "application/json": {
            "schema": {
              "additionalProperties": false,
              "properties": {
                "data": {
                  "additionalProperties": false,
                  "description": "Always null.",
                  "nullable": true,
                  "type": "object"
                },
                "error": {
                  "additionalProperties": false,
                  "properties": {
                    "args": {
                      "additionalProperties": {},
                      "description": "Structured details such as the rejected parameter.",
                      "type": "object"
                    },
                    "code": {
                      "enum": [
                        "RATE_LIMITED"
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "Correlation id to quote to support.",
                      "type": "string"
                    },
                    "message": {
                      "description": "User-safe message.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "data",
                "error"
              ],
              "type": "object"
            }
          }
        },
        "description": "Rate limit or row budget exceeded; retry after the time in Retry-After.",
        "headers": {
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimit-Limit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimit-Remaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimit-Reset"
          },
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          },
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "x-retryable": true
      },
      "Error500InternalError": {
        "content": {
          "application/json": {
            "schema": {
              "additionalProperties": false,
              "properties": {
                "data": {
                  "additionalProperties": false,
                  "description": "Always null.",
                  "nullable": true,
                  "type": "object"
                },
                "error": {
                  "additionalProperties": false,
                  "properties": {
                    "args": {
                      "additionalProperties": {},
                      "description": "Structured details such as the rejected parameter.",
                      "type": "object"
                    },
                    "code": {
                      "enum": [
                        "INTERNAL_ERROR"
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "Correlation id to quote to support.",
                      "type": "string"
                    },
                    "message": {
                      "description": "User-safe message.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "data",
                "error"
              ],
              "type": "object"
            }
          }
        },
        "description": "Unexpected server error.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "x-retryable": false
      },
      "Error503AuditUnavailableBillingUnavailable": {
        "content": {
          "application/json": {
            "schema": {
              "additionalProperties": false,
              "properties": {
                "data": {
                  "additionalProperties": false,
                  "description": "Always null.",
                  "nullable": true,
                  "type": "object"
                },
                "error": {
                  "additionalProperties": false,
                  "properties": {
                    "args": {
                      "additionalProperties": {},
                      "description": "Structured details such as the rejected parameter.",
                      "type": "object"
                    },
                    "code": {
                      "enum": [
                        "AUDIT_UNAVAILABLE",
                        "BILLING_UNAVAILABLE"
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "Correlation id to quote to support.",
                      "type": "string"
                    },
                    "message": {
                      "description": "User-safe message.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "data",
                "error"
              ],
              "type": "object"
            }
          }
        },
        "description": "A dependency is temporarily unavailable; retry later.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "x-retryable": true
      },
      "Error503BillingUnavailable": {
        "content": {
          "application/json": {
            "schema": {
              "additionalProperties": false,
              "properties": {
                "data": {
                  "additionalProperties": false,
                  "description": "Always null.",
                  "nullable": true,
                  "type": "object"
                },
                "error": {
                  "additionalProperties": false,
                  "properties": {
                    "args": {
                      "additionalProperties": {},
                      "description": "Structured details such as the rejected parameter.",
                      "type": "object"
                    },
                    "code": {
                      "enum": [
                        "BILLING_UNAVAILABLE"
                      ],
                      "type": "string"
                    },
                    "id": {
                      "description": "Correlation id to quote to support.",
                      "type": "string"
                    },
                    "message": {
                      "description": "User-safe message.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ],
                  "type": "object"
                }
              },
              "required": [
                "data",
                "error"
              ],
              "type": "object"
            }
          }
        },
        "description": "A dependency is temporarily unavailable; retry later.",
        "headers": {
          "X-Request-ID": {
            "$ref": "#/components/headers/X-Request-ID"
          }
        },
        "x-retryable": true
      }
    },
    "examples": {
      "CaseListWithoutPii": {
        "summary": "Token with jml:read only; name and email are absent.",
        "value": {
          "data": [
            {
              "caseId": "lfc_example000001",
              "employee": {
                "employeeId": "empl_example000001",
                "emailMasked": "j***@example.com",
                "department": "Engineering",
                "jobTitle": "Engineer",
                "employmentType": "FULL_TIME",
                "employeeStatus": "TERMINATED",
                "startDate": "2021-03-01",
                "endDate": "2026-09-15"
              },
              "status": "OPEN",
              "openedAt": "2026-09-15T08:00:00Z",
              "dueAt": "2026-09-22T08:00:00Z",
              "summary": {
                "total": 3,
                "revoked": 1,
                "outstanding": 1,
                "discrepancy": 1,
                "attested": 0
              },
              "clean": false
            }
          ],
          "error": null,
          "meta": {
            "limit": 25,
            "offset": 0,
            "total": 1,
            "accessDataAsOf": "2026-09-29T02:00:00Z"
          }
        }
      },
      "CaseListWithPii": {
        "summary": "Token with jml:read and pii:read; name and email are present.",
        "value": {
          "data": [
            {
              "caseId": "lfc_example000001",
              "employee": {
                "employeeId": "empl_example000001",
                "emailMasked": "j***@example.com",
                "name": "Jane Doe",
                "email": "jane.doe@example.com",
                "department": "Engineering",
                "jobTitle": "Engineer",
                "employmentType": "FULL_TIME",
                "employeeStatus": "TERMINATED",
                "startDate": "2021-03-01",
                "endDate": "2026-09-15"
              },
              "status": "OPEN",
              "openedAt": "2026-09-15T08:00:00Z",
              "dueAt": null,
              "summary": {
                "total": 3,
                "revoked": 1,
                "outstanding": 1,
                "discrepancy": 1,
                "attested": 0
              },
              "clean": false
            }
          ],
          "error": null,
          "meta": {
            "limit": 25,
            "offset": 0,
            "total": 1,
            "accessDataAsOf": null
          }
        }
      },
      "CaseWithoutPii": {
        "value": {
          "data": {
            "caseId": "lfc_example000001",
            "employee": {
              "employeeId": "empl_example000001",
              "emailMasked": "j***@example.com"
            },
            "status": "COMPLETED",
            "openedAt": "2026-09-15T08:00:00Z",
            "dueAt": null,
            "summary": {
              "total": 1,
              "revoked": 1,
              "outstanding": 0,
              "discrepancy": 0,
              "attested": 0
            },
            "clean": true
          },
          "error": null,
          "meta": {
            "accessDataAsOf": "2026-09-29T02:00:00Z"
          }
        }
      },
      "ItemList": {
        "value": {
          "data": [
            {
              "itemId": "ltsk_example000001",
              "itemKey": "lfc_example000001:ast_example000001",
              "taskId": "ltsk_example000001",
              "caseId": "lfc_example000001",
              "employeeId": "empl_example000001",
              "assetId": "ast_example000001",
              "assetName": "Example CRM",
              "status": "DISCREPANCY",
              "taskStatus": "COMPLETED",
              "accessStatus": "ACTIVE",
              "source": "TASK",
              "openedAt": "2026-09-15T08:00:00Z",
              "taskCompletedAt": "2026-09-16T10:30:00Z",
              "accessLastDetectedAt": "2026-09-29T02:00:00Z"
            }
          ],
          "error": null,
          "meta": {
            "limit": 25,
            "offset": 0,
            "total": 1,
            "summary": {
              "total": 1,
              "revoked": 0,
              "outstanding": 0,
              "discrepancy": 1,
              "attested": 0
            },
            "accessDataAsOf": "2026-09-29T02:00:00Z"
          }
        }
      },
      "OnboardingCaseListWithoutPii": {
        "summary": "Token with jml:read only; name and email are absent.",
        "value": {
          "data": [
            {
              "caseId": "lfc_example000002",
              "employee": {
                "employeeId": "empl_example000002",
                "emailMasked": "a***@example.com",
                "department": "Sales",
                "jobTitle": "Account Executive",
                "employmentType": "FULL_TIME",
                "employeeStatus": "ACTIVE",
                "startDate": "2026-10-01"
              },
              "status": "IN_PROGRESS",
              "openedAt": "2026-09-25T08:00:00Z",
              "dueAt": "2026-10-01T08:00:00Z",
              "summary": {
                "total": 3,
                "granted": 1,
                "pending": 1,
                "attested": 1
              },
              "ready": false,
              "overdue": true,
              "generatedAt": "2026-09-25T08:00:00Z",
              "generatedFromProfileIds": [
                "aprf_example000001"
              ]
            }
          ],
          "error": null,
          "meta": {
            "limit": 25,
            "offset": 0,
            "total": 1,
            "accessDataAsOf": "2026-09-29T02:00:00Z"
          }
        }
      },
      "OnboardingCaseListWithPii": {
        "summary": "Token with jml:read and pii:read; name and email are present.",
        "value": {
          "data": [
            {
              "caseId": "lfc_example000002",
              "employee": {
                "employeeId": "empl_example000002",
                "emailMasked": "a***@example.com",
                "name": "Alex Example",
                "email": "alex.example@example.com",
                "department": "Sales",
                "jobTitle": "Account Executive",
                "employmentType": "FULL_TIME",
                "employeeStatus": "ACTIVE",
                "startDate": "2026-10-01"
              },
              "status": "OPEN",
              "openedAt": "2026-09-25T08:00:00Z",
              "dueAt": null,
              "summary": {
                "total": 2,
                "granted": 2,
                "pending": 0,
                "attested": 0
              },
              "ready": true,
              "overdue": false,
              "generatedAt": "2026-09-25T08:00:00Z",
              "generatedFromProfileIds": [
                "aprf_example000001",
                "aprf_example000002"
              ]
            }
          ],
          "error": null,
          "meta": {
            "limit": 25,
            "offset": 0,
            "total": 1,
            "accessDataAsOf": "2026-09-29T02:00:00Z"
          }
        }
      },
      "OnboardingCaseWithoutPii": {
        "value": {
          "data": {
            "caseId": "lfc_example000002",
            "employee": {
              "employeeId": "empl_example000002",
              "emailMasked": "a***@example.com",
              "employeeStatus": "ACTIVE"
            },
            "status": "COMPLETED",
            "openedAt": "2026-09-25T08:00:00Z",
            "dueAt": "2026-10-01T08:00:00Z",
            "summary": {
              "total": 1,
              "granted": 1,
              "pending": 0,
              "attested": 0
            },
            "ready": true,
            "overdue": false,
            "generatedAt": null,
            "generatedFromProfileIds": []
          },
          "error": null,
          "meta": {
            "accessDataAsOf": "2026-09-29T02:00:00Z"
          }
        }
      },
      "OnboardingItemList": {
        "value": {
          "data": [
            {
              "itemId": "ltsk_example000002",
              "itemKey": "lfc_example000002:ast_example000002",
              "taskId": "ltsk_example000002",
              "caseId": "lfc_example000002",
              "employeeId": "empl_example000002",
              "assetId": "ast_example000002",
              "assetName": "Example Chat",
              "status": "GRANTED",
              "accessStatus": "ACTIVE",
              "accessLastDetectedAt": "2026-09-29T02:00:00Z",
              "sourceProfileIds": [
                "aprf_example000001"
              ],
              "attestedAt": null,
              "source": "PROFILE",
              "openedAt": "2026-09-25T08:00:00Z",
              "dueAt": "2026-10-01T08:00:00Z"
            },
            {
              "itemId": "ltsk_example000003",
              "itemKey": "lfc_example000002:ltsk_example000003",
              "taskId": "ltsk_example000003",
              "caseId": "lfc_example000002",
              "employeeId": "empl_example000002",
              "assetId": null,
              "assetName": null,
              "status": "ATTESTED",
              "accessStatus": null,
              "accessLastDetectedAt": null,
              "sourceProfileIds": [],
              "attestedAt": "2026-09-26T09:15:00Z",
              "source": "MANUAL_TASK",
              "openedAt": "2026-09-25T08:00:00Z",
              "dueAt": "2026-10-01T08:00:00Z"
            }
          ],
          "error": null,
          "meta": {
            "limit": 25,
            "offset": 0,
            "total": 2,
            "summary": {
              "total": 2,
              "granted": 1,
              "pending": 0,
              "attested": 1
            },
            "accessDataAsOf": "2026-09-29T02:00:00Z"
          }
        }
      },
      "OnboardingCaseNotReady": {
        "summary": "A joiner case that is not ready and overdue (3 items, 1 granted, 1 pending, 1 marked done).",
        "value": {
          "data": {
            "caseId": "lfc_example000002",
            "employee": {
              "employeeId": "empl_example000002",
              "emailMasked": "a***@example.com",
              "department": "Sales",
              "jobTitle": "Account Executive",
              "employmentType": "FULL_TIME",
              "employeeStatus": "ACTIVE",
              "startDate": "2026-10-01"
            },
            "status": "IN_PROGRESS",
            "openedAt": "2026-09-25T08:00:00Z",
            "dueAt": "2026-10-01T08:00:00Z",
            "summary": {
              "total": 3,
              "granted": 1,
              "pending": 1,
              "attested": 1
            },
            "ready": false,
            "overdue": true,
            "generatedAt": "2026-09-25T08:00:00Z",
            "generatedFromProfileIds": [
              "aprf_example000001"
            ]
          },
          "error": null,
          "meta": {
            "accessDataAsOf": "2026-09-29T02:00:00Z"
          }
        }
      },
      "OnboardingItemListPending": {
        "summary": "Items still waiting for access, as returned with filter[status][eq]=PENDING. The item carries only employeeId, no name or email.",
        "value": {
          "data": [
            {
              "itemId": "ltsk_example000002",
              "itemKey": "lfc_example000002:ast_example000002",
              "taskId": "ltsk_example000002",
              "caseId": "lfc_example000002",
              "employeeId": "empl_example000002",
              "assetId": "ast_example000002",
              "assetName": "Example Chat",
              "status": "PENDING",
              "accessStatus": null,
              "accessLastDetectedAt": null,
              "sourceProfileIds": [
                "aprf_example000001"
              ],
              "attestedAt": null,
              "source": "PROFILE",
              "openedAt": "2026-09-25T08:00:00Z",
              "dueAt": "2026-10-01T08:00:00Z"
            }
          ],
          "error": null,
          "meta": {
            "limit": 50,
            "offset": 0,
            "total": 1,
            "summary": {
              "total": 1,
              "granted": 0,
              "pending": 1,
              "attested": 0
            },
            "accessDataAsOf": "2026-09-29T02:00:00Z"
          }
        }
      },
      "SbomList": {
        "value": {
          "data": [
            {
              "sbomId": "sbom_example000001",
              "orgId": "org_example000001",
              "name": "example-service",
              "version": "2026.9.1",
              "assetId": "ast_example000001",
              "source": "go.sum",
              "sourceRef": "go.sum",
              "repoUrl": "https://git.example.com/example-org/example-service",
              "branch": "main",
              "componentCount": 184,
              "findingsCritical": 1,
              "findingsHigh": 4,
              "findingsMedium": 11,
              "findingsLow": 6,
              "lastMatchedAt": "2026-09-08T02:14:00Z",
              "createdAt": "2026-09-01T09:32:41Z",
              "updatedAt": "2026-09-08T02:14:00Z"
            }
          ]
        }
      },
      "SbomOne": {
        "value": {
          "data": {
            "sbomId": "sbom_example000001",
            "orgId": "org_example000001",
            "name": "example-service",
            "version": "2026.9.1",
            "source": "go.sum",
            "sourceRef": "go.sum",
            "componentCount": 184,
            "findingsCritical": 1,
            "findingsHigh": 4,
            "findingsMedium": 11,
            "findingsLow": 6,
            "lastMatchedAt": "2026-09-08T02:14:00Z",
            "createdAt": "2026-09-01T09:32:41Z",
            "updatedAt": "2026-09-08T02:14:00Z"
          }
        }
      },
      "SbomCreated": {
        "value": {
          "data": {
            "sbomId": "sbom_example000002",
            "orgId": "org_example000001",
            "name": "example-service",
            "version": "2026.9.1",
            "source": "manual",
            "repoUrl": "https://git.example.com/example-org/example-service",
            "branch": "main",
            "componentCount": 0,
            "findingsCritical": 0,
            "findingsHigh": 0,
            "findingsMedium": 0,
            "findingsLow": 0,
            "createdAt": "2026-09-01T09:32:41Z",
            "updatedAt": "2026-09-01T09:32:41Z"
          }
        }
      },
      "SbomUploaded": {
        "value": {
          "data": {
            "sbomId": "sbom_example000003",
            "orgId": "org_example000001",
            "name": "example-service",
            "version": "2026.9.1",
            "source": "go.sum",
            "componentCount": 0,
            "findingsCritical": 0,
            "findingsHigh": 0,
            "findingsMedium": 0,
            "findingsLow": 0,
            "createdAt": "2026-09-01T09:32:41Z",
            "updatedAt": "2026-09-01T09:32:41Z"
          }
        }
      },
      "ComponentList": {
        "value": {
          "data": [
            {
              "componentId": "comp_example000001",
              "orgId": "org_example000001",
              "sbomId": "sbom_example000001",
              "name": "example.com/lib/parser",
              "version": "v1.9.1",
              "ecosystem": "go",
              "purl": "pkg:golang/example.com/lib/parser",
              "direct": true,
              "license": "MIT",
              "createdAt": "2026-09-01T09:32:41Z",
              "updatedAt": "2026-09-01T09:32:41Z"
            }
          ]
        }
      },
      "FindingList": {
        "value": {
          "data": [
            {
              "findingId": "vfin_example000001",
              "orgId": "org_example000001",
              "sbomId": "sbom_example000001",
              "componentId": "comp_example000001",
              "cveId": "CVE-2024-00000",
              "cveSource": "nvd",
              "matchMethod": "purl_version_range",
              "confidence": "high",
              "severity": "HIGH",
              "cvssV3Score": 7.5,
              "status": "open",
              "slaBreach": false,
              "fixedVersion": "v1.9.2",
              "firstSeenAt": "2026-09-02T02:10:00Z",
              "updatedAt": "2026-09-02T02:10:00Z"
            }
          ]
        }
      },
      "VendorOne": {
        "value": {
          "data": {
            "vendorId": "vendor_example000001",
            "orgId": "org_example000001",
            "name": "Example Analytics",
            "website": "https://vendor.example.com",
            "type": "commercial",
            "riskTier": 2,
            "assessmentStatus": "in_progress",
            "lastAssessedAt": "2026-07-14T10:00:00Z",
            "notes": "Processes pseudonymised usage events only.",
            "createdAt": "2026-03-02T11:20:05Z",
            "updatedAt": "2026-09-05T08:41:12Z"
          }
        }
      },
      "VendorList": {
        "value": {
          "data": [
            {
              "vendorId": "vendor_example000001",
              "orgId": "org_example000001",
              "name": "Example Analytics",
              "website": "https://vendor.example.com",
              "type": "commercial",
              "riskTier": 2,
              "assessmentStatus": "in_progress",
              "createdAt": "2026-03-02T11:20:05Z",
              "updatedAt": "2026-09-05T08:41:12Z"
            }
          ]
        }
      },
      "TemplateList": {
        "value": {
          "data": [
            {
              "templateId": "satpl_builtin_supplier_security_privacy_v1",
              "templateKey": "supplier_security_privacy",
              "version": 1,
              "titleKey": "supplier.template.builtin.title",
              "title": {
                "en": "Supplier security and privacy"
              },
              "source": "builtin",
              "status": "published",
              "active": true,
              "isDefault": true,
              "questionCount": 62,
              "updatedAt": "2026-09-01T09:00:00Z",
              "permissions": {
                "canEdit": false,
                "canSubmit": false,
                "canWithdraw": false,
                "canReject": false,
                "canPublish": null,
                "canSetDefault": false,
                "canArchive": false,
                "canDelete": false,
                "publishBlockedReason": null
              }
            }
          ],
          "meta": {
            "total": 1,
            "limit": 25
          }
        }
      },
      "TemplateDraft": {
        "value": {
          "data": {
            "templateId": "satpl_1hgyun41rx48",
            "templateKey": "tpl_1hgyun41rx49",
            "version": 0,
            "titleKey": "",
            "title": {
              "en": "Example vendor security review"
            },
            "modes": [],
            "source": "authored",
            "status": "draft",
            "active": false,
            "questionCount": 0,
            "revision": 3,
            "createdAt": "2026-10-09T08:15:00Z",
            "updatedAt": "2026-10-09T08:20:00Z",
            "sections": [
              {
                "sectionId": "sect_1hgyun41rx4a",
                "titleKey": "",
                "title": {
                  "en": "Governance"
                },
                "order": 1,
                "questions": []
              }
            ],
            "limits": {
              "maxSections": 20,
              "maxQuestionsPerSection": 50,
              "maxQuestionsPerTemplate": 300,
              "maxOptionsPerQuestion": 12
            },
            "permissions": {
              "canEdit": true,
              "canSubmit": true,
              "canWithdraw": false,
              "canReject": false,
              "canPublish": false,
              "canSetDefault": false,
              "canArchive": false,
              "canDelete": true,
              "publishBlockedReason": null
            }
          }
        }
      },
      "TemplateValidate": {
        "value": {
          "data": {
            "violations": [],
            "warnings": [
              {
                "code": "W2_MISSING_TRANSLATION",
                "path": "sections[0].title",
                "parameters": {
                  "locale": "ru"
                }
              }
            ]
          }
        }
      },
      "TemplatePreview": {
        "value": {
          "data": {
            "impact": {
              "fromVersion": null,
              "toVersion": 1,
              "baselineIsBuiltin": true,
              "baselineKey": "supplier_security_privacy",
              "maxPenalty": [
                {
                  "mode": "general",
                  "before": 100,
                  "after": 100,
                  "change": 0,
                  "unloseableBefore": 0,
                  "unloseableAfter": 0,
                  "deltaPct": 0
                }
              ],
              "criticalOptionCount": {
                "before": 4,
                "after": 4,
                "change": 0
              },
              "scoreableQuestionCount": {
                "before": 60,
                "after": 60,
                "change": 0,
                "added": 0,
                "removed": 0
              },
              "weightChanges": [],
              "riskValueChanges": [],
              "severityChanges": [],
              "addedQuestions": [],
              "removedQuestions": [],
              "changes": [],
              "requiresAcknowledgement": false,
              "acknowledgementReasons": [],
              "acknowledgementRowCount": 0
            },
            "violations": [],
            "warnings": [],
            "permissions": {
              "canEdit": true,
              "canSubmit": true,
              "canWithdraw": false,
              "canReject": false,
              "canPublish": false,
              "canSetDefault": false,
              "canArchive": false,
              "canDelete": true,
              "publishBlockedReason": null
            }
          }
        }
      },
      "TemplateDraftNew": {
        "value": {
          "data": {
            "templateId": "satpl_1hgyun41rx48",
            "templateKey": "tpl_1hgyun41rx49",
            "version": 0,
            "titleKey": "",
            "title": {
              "en": "Example vendor security review"
            },
            "modes": [],
            "source": "authored",
            "status": "draft",
            "active": false,
            "questionCount": 0,
            "revision": 1,
            "createdAt": "2026-10-09T08:15:00Z",
            "updatedAt": "2026-10-09T08:20:00Z",
            "sections": [
              {
                "sectionId": "sect_1hgyun41rx4a",
                "titleKey": "",
                "title": {
                  "en": "Governance"
                },
                "order": 1,
                "questions": []
              }
            ],
            "limits": {
              "maxSections": 20,
              "maxQuestionsPerSection": 50,
              "maxQuestionsPerTemplate": 300,
              "maxOptionsPerQuestion": 12
            },
            "permissions": {
              "canEdit": true,
              "canSubmit": true,
              "canWithdraw": false,
              "canReject": false,
              "canPublish": false,
              "canSetDefault": false,
              "canArchive": false,
              "canDelete": true,
              "publishBlockedReason": null
            }
          }
        }
      },
      "TemplateDraftWithSection": {
        "value": {
          "data": {
            "templateId": "satpl_1hgyun41rx48",
            "templateKey": "tpl_1hgyun41rx49",
            "version": 0,
            "titleKey": "",
            "title": {
              "en": "Example vendor security review"
            },
            "modes": [],
            "source": "authored",
            "status": "draft",
            "active": false,
            "questionCount": 0,
            "revision": 4,
            "createdAt": "2026-10-09T08:15:00Z",
            "updatedAt": "2026-10-09T08:20:00Z",
            "sections": [
              {
                "sectionId": "sect_1hgyun41rx4a",
                "titleKey": "",
                "title": {
                  "en": "Governance"
                },
                "order": 1,
                "questions": []
              },
              {
                "sectionId": "sect_1hgyun41rx4b",
                "titleKey": "",
                "title": {
                  "en": "Access control"
                },
                "order": 2,
                "questions": []
              }
            ],
            "limits": {
              "maxSections": 20,
              "maxQuestionsPerSection": 50,
              "maxQuestionsPerTemplate": 300,
              "maxOptionsPerQuestion": 12
            },
            "permissions": {
              "canEdit": true,
              "canSubmit": true,
              "canWithdraw": false,
              "canReject": false,
              "canPublish": false,
              "canSetDefault": false,
              "canArchive": false,
              "canDelete": true,
              "publishBlockedReason": null
            }
          }
        }
      },
      "TemplateDraftRenamedSection": {
        "value": {
          "data": {
            "templateId": "satpl_1hgyun41rx48",
            "templateKey": "tpl_1hgyun41rx49",
            "version": 0,
            "titleKey": "",
            "title": {
              "en": "Example vendor security review"
            },
            "modes": [],
            "source": "authored",
            "status": "draft",
            "active": false,
            "questionCount": 0,
            "revision": 4,
            "createdAt": "2026-10-09T08:15:00Z",
            "updatedAt": "2026-10-09T08:20:00Z",
            "sections": [
              {
                "sectionId": "sect_1hgyun41rx4a",
                "titleKey": "",
                "title": {
                  "en": "Governance"
                },
                "order": 1,
                "questions": []
              },
              {
                "sectionId": "sect_1hgyun41rx4b",
                "titleKey": "",
                "title": {
                  "en": "Access management"
                },
                "order": 2,
                "questions": []
              }
            ],
            "limits": {
              "maxSections": 20,
              "maxQuestionsPerSection": 50,
              "maxQuestionsPerTemplate": 300,
              "maxOptionsPerQuestion": 12
            },
            "permissions": {
              "canEdit": true,
              "canSubmit": true,
              "canWithdraw": false,
              "canReject": false,
              "canPublish": false,
              "canSetDefault": false,
              "canArchive": false,
              "canDelete": true,
              "publishBlockedReason": null
            }
          }
        }
      },
      "TemplateDraftWithQuestion": {
        "value": {
          "data": {
            "templateId": "satpl_1hgyun41rx48",
            "templateKey": "tpl_1hgyun41rx49",
            "version": 0,
            "titleKey": "",
            "title": {
              "en": "Example vendor security review"
            },
            "modes": [],
            "source": "authored",
            "status": "draft",
            "active": false,
            "questionCount": 1,
            "revision": 4,
            "createdAt": "2026-10-09T08:15:00Z",
            "updatedAt": "2026-10-09T08:20:00Z",
            "sections": [
              {
                "sectionId": "sect_1hgyun41rx4a",
                "titleKey": "",
                "title": {
                  "en": "Governance"
                },
                "order": 1,
                "questions": [
                  {
                    "questionId": "saq_1hgyun41rx4d",
                    "textKey": "",
                    "text": {
                      "en": "Is data encrypted at rest?"
                    },
                    "answerType": "single_select",
                    "required": true,
                    "modes": [],
                    "domain": "operations",
                    "weight": 8,
                    "authored": true,
                    "options": [
                      {
                        "optionId": "saqo_1hgyun41rx4e",
                        "labelKey": "",
                        "label": {
                          "en": "Yes, all stores"
                        },
                        "riskValue": 0
                      },
                      {
                        "optionId": "saqo_1hgyun41rx4f",
                        "labelKey": "",
                        "label": {
                          "en": "No"
                        },
                        "riskValue": 4,
                        "findingSeverity": "high"
                      }
                    ]
                  }
                ]
              }
            ],
            "limits": {
              "maxSections": 20,
              "maxQuestionsPerSection": 50,
              "maxQuestionsPerTemplate": 300,
              "maxOptionsPerQuestion": 12
            },
            "permissions": {
              "canEdit": true,
              "canSubmit": true,
              "canWithdraw": false,
              "canReject": false,
              "canPublish": false,
              "canSetDefault": false,
              "canArchive": false,
              "canDelete": true,
              "publishBlockedReason": null
            }
          }
        }
      },
      "TemplateDraftWithOption": {
        "value": {
          "data": {
            "templateId": "satpl_1hgyun41rx48",
            "templateKey": "tpl_1hgyun41rx49",
            "version": 0,
            "titleKey": "",
            "title": {
              "en": "Example vendor security review"
            },
            "modes": [],
            "source": "authored",
            "status": "draft",
            "active": false,
            "questionCount": 1,
            "revision": 5,
            "createdAt": "2026-10-09T08:15:00Z",
            "updatedAt": "2026-10-09T08:20:00Z",
            "sections": [
              {
                "sectionId": "sect_1hgyun41rx4a",
                "titleKey": "",
                "title": {
                  "en": "Governance"
                },
                "order": 1,
                "questions": [
                  {
                    "questionId": "saq_1hgyun41rx4d",
                    "textKey": "",
                    "text": {
                      "en": "Is data encrypted at rest?"
                    },
                    "answerType": "single_select",
                    "required": true,
                    "modes": [],
                    "domain": "operations",
                    "weight": 8,
                    "authored": true,
                    "options": [
                      {
                        "optionId": "saqo_1hgyun41rx4e",
                        "labelKey": "",
                        "label": {
                          "en": "Yes, all stores"
                        },
                        "riskValue": 0
                      },
                      {
                        "optionId": "saqo_1hgyun41rx4f",
                        "labelKey": "",
                        "label": {
                          "en": "No"
                        },
                        "riskValue": 4,
                        "findingSeverity": "high"
                      },
                      {
                        "optionId": "saqo_1hgyun41rx4g",
                        "labelKey": "",
                        "label": {
                          "en": "Partly"
                        },
                        "riskValue": 2,
                        "findingSeverity": "medium"
                      }
                    ]
                  }
                ]
              }
            ],
            "limits": {
              "maxSections": 20,
              "maxQuestionsPerSection": 50,
              "maxQuestionsPerTemplate": 300,
              "maxOptionsPerQuestion": 12
            },
            "permissions": {
              "canEdit": true,
              "canSubmit": true,
              "canWithdraw": false,
              "canReject": false,
              "canPublish": false,
              "canSetDefault": false,
              "canArchive": false,
              "canDelete": true,
              "publishBlockedReason": null
            }
          }
        }
      },
      "TemplateSubmitted": {
        "value": {
          "data": {
            "templateId": "satpl_1hgyun41rx48",
            "templateKey": "tpl_1hgyun41rx49",
            "version": 0,
            "titleKey": "",
            "title": {
              "en": "Example vendor security review"
            },
            "modes": [],
            "source": "authored",
            "status": "submitted",
            "active": false,
            "questionCount": 0,
            "revision": 3,
            "createdAt": "2026-10-09T08:15:00Z",
            "updatedAt": "2026-10-09T08:20:00Z",
            "sections": [
              {
                "sectionId": "sect_1hgyun41rx4a",
                "titleKey": "",
                "title": {
                  "en": "Governance"
                },
                "order": 1,
                "questions": []
              }
            ],
            "limits": {
              "maxSections": 20,
              "maxQuestionsPerSection": 50,
              "maxQuestionsPerTemplate": 300,
              "maxOptionsPerQuestion": 12
            },
            "permissions": {
              "canEdit": false,
              "canSubmit": false,
              "canWithdraw": true,
              "canReject": false,
              "canPublish": false,
              "canSetDefault": false,
              "canArchive": false,
              "canDelete": false,
              "publishBlockedReason": null
            }
          }
        }
      },
      "TemplateVersion": {
        "value": {
          "data": {
            "templateId": "satpl_1hgyun41rx50",
            "templateKey": "tpl_1hgyun41rx49",
            "version": 2,
            "titleKey": "",
            "title": {
              "en": "Example vendor security review"
            },
            "modes": [],
            "source": "authored",
            "status": "published",
            "active": true,
            "isDefault": false,
            "questionCount": 1,
            "contentHash": "9f2c4e7a1b3d5f6081a2c3d4e5f60718293a4b5c6d7e8f901122334455667788",
            "parentVersion": 1,
            "publishedAt": "2026-10-10T12:00:00Z",
            "publishedBy": "usr_1hgyq7m2k9xa",
            "createdAt": "2026-10-09T08:15:00Z",
            "updatedAt": "2026-10-10T12:00:00Z",
            "sections": [
              {
                "sectionId": "sect_1hgyun41rx4a",
                "titleKey": "",
                "title": {
                  "en": "Governance"
                },
                "order": 1,
                "questions": [
                  {
                    "questionId": "saq_1hgyun41rx4d",
                    "textKey": "",
                    "text": {
                      "en": "Is data encrypted at rest?"
                    },
                    "answerType": "single_select",
                    "required": true,
                    "modes": [],
                    "domain": "operations",
                    "weight": 10,
                    "authored": true,
                    "options": [
                      {
                        "optionId": "saqo_1hgyun41rx4e",
                        "labelKey": "",
                        "label": {
                          "en": "Yes, all stores"
                        },
                        "riskValue": 0
                      },
                      {
                        "optionId": "saqo_1hgyun41rx4f",
                        "labelKey": "",
                        "label": {
                          "en": "No"
                        },
                        "riskValue": 4,
                        "findingSeverity": "high"
                      },
                      {
                        "optionId": "saqo_1hgyun41rx4g",
                        "labelKey": "",
                        "label": {
                          "en": "Partly"
                        },
                        "riskValue": 2,
                        "findingSeverity": "medium"
                      }
                    ]
                  }
                ]
              }
            ],
            "limits": {
              "maxSections": 20,
              "maxQuestionsPerSection": 50,
              "maxQuestionsPerTemplate": 300,
              "maxOptionsPerQuestion": 12
            },
            "permissions": {
              "canEdit": false,
              "canSubmit": false,
              "canWithdraw": false,
              "canReject": false,
              "canPublish": null,
              "canSetDefault": true,
              "canArchive": true,
              "canDelete": false,
              "publishBlockedReason": null
            }
          },
          "meta": {
            "contentHashVerified": true
          }
        }
      },
      "TemplateVersionDiff": {
        "value": {
          "data": {
            "templateKey": "tpl_1hgyun41rx49",
            "fromVersion": 1,
            "toVersion": 2,
            "rows": [
              {
                "kind": "questionModified",
                "questionId": "saq_1hgyun41rx4d",
                "sectionId": "sect_1hgyun41rx4a",
                "fields": [
                  {
                    "field": "weight",
                    "before": 8,
                    "after": 10
                  }
                ]
              },
              {
                "kind": "optionAdded",
                "questionId": "saq_1hgyun41rx4d",
                "sectionId": "sect_1hgyun41rx4a",
                "optionId": "saqo_1hgyun41rx4g"
              },
              {
                "kind": "questionRemoved",
                "questionId": "saq_1hgyun41rx4c",
                "sectionId": "sect_1hgyun41rx4a",
                "referencedByAssessments": 3
              }
            ]
          }
        }
      },
      "TemplateTranslated": {
        "value": {
          "data": {
            "text": "Шифруются ли данные в состоянии покоя?"
          }
        }
      },
      "TokenList": {
        "value": {
          "data": [
            {
              "tokenId": "tok_1hgyun41rx48",
              "name": "GitHub Actions SBOM upload",
              "prefix": "aci_XXXX",
              "scopes": [
                "sbom:write"
              ],
              "lastUsedAt": "2026-10-08T03:12:44Z",
              "activity": {
                "day": "2026-10-08",
                "requests": 42,
                "rows": 1180,
                "distinctRoutes": 3,
                "lastIp": "203.0.113.7",
                "lastRouteId": "/api/v1/sscs/sboms"
              },
              "createdBy": "usr_1hgyq2mw7c3k",
              "createdAt": "2026-09-02T10:00:00Z",
              "updatedAt": "2026-10-08T03:12:44Z"
            },
            {
              "tokenId": "tok_1hgz02bd9k1p",
              "name": "HR leaver sync",
              "prefix": "aci_YYYY",
              "scopes": [
                "jml:read"
              ],
              "expiresAt": "2027-10-01T00:00:00Z",
              "revokedAt": "2026-10-05T08:30:00Z",
              "revokedBy": "usr_1hgyq2mw7c3k",
              "createdBy": "usr_1hgyq2mw7c3k",
              "createdAt": "2026-09-15T12:00:00Z",
              "updatedAt": "2026-10-05T08:30:00Z"
            }
          ]
        }
      },
      "CreatedToken": {
        "value": {
          "data": {
            "tokenId": "tok_1hgz7c0aw2mf",
            "name": "GitHub Actions SBOM upload",
            "prefix": "aci_XXXX",
            "scopes": [
              "sbom:write"
            ],
            "createdBy": "usr_1hgyq2mw7c3k",
            "createdAt": "2026-10-09T09:00:00Z",
            "updatedAt": "2026-10-09T09:00:00Z",
            "tokenValue": "aci_<redacted>"
          }
        }
      },
      "ScopeCatalogue": {
        "value": {
          "data": [
            {
              "scope": "risk:read",
              "group": "risk",
              "resource": "risk",
              "requiresExpiry": false,
              "maxExpiryDays": 0,
              "creatorRoles": [
                "owner",
                "manager"
              ],
              "enabled": true
            },
            {
              "scope": "jml:read",
              "group": "jml",
              "resource": "jml",
              "requiresExpiry": true,
              "maxExpiryDays": 365,
              "creatorRoles": [
                "owner",
                "manager"
              ],
              "enabled": true
            }
          ]
        }
      },
      "Healthy": {
        "summary": "The API is running",
        "value": {
          "data": {
            "status": "ok"
          }
        }
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "aci_ API token",
        "description": "API token created in the console (prefix `aci_`). Required scope: `jml:read`; adding\n`pii:read` also discloses employee name and email. Sent as `Authorization: Bearer aci_<redacted>`.\n"
      },
      "consoleSession": {
        "type": "http",
        "scheme": "bearer",
        "description": "The signed-in console session of an organization Owner or Manager. API tokens (`aci_`) are\nrefused with 403.\n"
      }
    },
    "parameters": {
      "SbomId": {
        "name": "sbomId",
        "in": "path",
        "required": true,
        "description": "SBOM id.",
        "schema": {
          "type": "string"
        }
      },
      "FindingId": {
        "name": "findingId",
        "in": "path",
        "required": true,
        "description": "Finding id.",
        "schema": {
          "type": "string"
        }
      },
      "VendorId": {
        "name": "vendorId",
        "in": "path",
        "required": true,
        "description": "Vendor id.",
        "schema": {
          "type": "string"
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "required": false,
        "description": "Page size. Default 25, maximum 500.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 500,
          "default": 25
        }
      },
      "Offset": {
        "name": "offset",
        "in": "query",
        "required": false,
        "description": "Zero-based offset.",
        "schema": {
          "type": "integer",
          "minimum": 0,
          "default": 0
        }
      },
      "TemplateId": {
        "name": "templateId",
        "in": "path",
        "required": true,
        "description": "Questionnaire document id (`satpl_...`), or `satpl_builtin_supplier_security_privacy_v1` for the built-in one.",
        "schema": {
          "type": "string"
        }
      },
      "TemplateKey": {
        "name": "templateId",
        "in": "path",
        "required": true,
        "description": "The questionnaire's `templateKey`, which is shared by all its versions. Not a document `templateId`.",
        "schema": {
          "type": "string"
        }
      },
      "Version": {
        "name": "version",
        "in": "path",
        "required": true,
        "description": "Version number; 0 is an open draft.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "SectionId": {
        "name": "sectionId",
        "in": "path",
        "required": true,
        "description": "Section id, as returned in `sections[].sectionId`.",
        "schema": {
          "type": "string"
        }
      },
      "QuestionId": {
        "name": "questionId",
        "in": "path",
        "required": true,
        "description": "Question id, as returned in `sections[].questions[].questionId`.",
        "schema": {
          "type": "string"
        }
      },
      "OptionId": {
        "name": "optionId",
        "in": "path",
        "required": true,
        "description": "Option id, as returned in `questions[].options[].optionId`.",
        "schema": {
          "type": "string"
        }
      },
      "IfMatch": {
        "name": "If-Match",
        "in": "header",
        "required": false,
        "description": "The draft revision as `W/\"<revision>\"`, from the ETag header. Wins over a `revision` in the body. A write on an older revision fails with 409 STALE_REVISION.",
        "schema": {
          "type": "string",
          "pattern": "^W/\"[0-9]+\"$"
        }
      },
      "TokenId": {
        "name": "tokenId",
        "in": "path",
        "required": true,
        "description": "The token id (`tokenId` from the list).",
        "schema": {
          "type": "string"
        }
      }
    },
    "headers": {
      "ETag": {
        "description": "Weak ETag of the draft, `W/\"<revision>\"`. Send the number back as `revision` or in `If-Match`.",
        "schema": {
          "type": "string"
        }
      },
      "RateLimit-Limit": {
        "description": "Token bucket burst size.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimit-Remaining": {
        "description": "Whole requests left in the bucket.",
        "schema": {
          "type": "integer"
        }
      },
      "RateLimit-Reset": {
        "description": "Seconds until the bucket is full.",
        "schema": {
          "type": "integer"
        }
      },
      "Retry-After": {
        "description": "Seconds to wait before retrying.",
        "schema": {
          "type": "integer"
        }
      },
      "X-Request-ID": {
        "description": "Correlation id to quote to support.",
        "schema": {
          "type": "string"
        }
      }
    }
  }
}
