{
  "openapi": "3.0.1",
  "info": {
    "title": "AMLService",
    "version": "1.0"
  },
  "paths": {
    "/docs/reference": {
      "get": {
        "tags": [
          "AMLService"
        ],
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/docs/reference/{slug}": {
      "get": {
        "tags": [
          "AMLService"
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/docs/reference/assets/{file}": {
      "get": {
        "tags": [
          "AMLService"
        ],
        "parameters": [
          {
            "name": "file",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/swagger-ui": {
      "get": {
        "tags": [
          "AMLService"
        ],
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/swagger-ui/assets/{file}": {
      "get": {
        "tags": [
          "AMLService"
        ],
        "parameters": [
          {
            "name": "file",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/v1/audit": {
      "get": {
        "tags": [
          "Audit"
        ],
        "summary": "List/filter audit entries (newest first), paged — or CSV when csv is requested.\r\n            `X-Export-Truncated: true` is set on a CSV export that hit the export cap.",
        "parameters": [
          {
            "name": "action",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "targetType",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "take",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 50
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/AuditListResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditListResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditListResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/audit/verify": {
      "get": {
        "tags": [
          "Audit"
        ],
        "summary": "Verify the tenant's tamper-evident audit hash chain: walk the entries in order, recompute the\r\nSHA-256 chain, and report whether it is intact (and the first broken entry id if not).",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/AuditVerifyResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditVerifyResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditVerifyResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/screenings/batch": {
      "post": {
        "tags": [
          "BatchScreening"
        ],
        "summary": "Submit a JSON array of subjects; queues an ASYNCHRONOUS batch job. Returns `202 Accepted`\r\nwith a job id and NO results — the JSON-native equivalent of the file upload, for integrations\r\nthat build their payload programmatically rather than uploading a CSV/XLSX.",
        "description": "\n\r\n  <b>Asynchronous.</b> The rows are stored and this returns immediately with\r\n            `{ jobId, totalRows, status }`; nothing has been screened yet. A background processor works\r\n            the rows afterwards. Poll `GET /v1/screenings/batch/{jobId}` until `status` reaches\r\n            `completed` (or `failed`), then fetch `GET /v1/screenings/batch/{jobId}/results`.\r\n            The `Location` header on the 202 points at the status route. Statuses are\r\n            `pending` → `running` → `completed` | `failed`.\r\n            \r\n\n\r\n  <b>Same subject shape as `POST /v1/screenings/bulk`.</b> A JSON list that screens\r\n            synchronously on `/bulk` can be sent HERE to screen asynchronously and receive a job id\r\n            instead of inline results — the right choice for large volumes that would otherwise exceed the\r\n            caller's HTTP timeout. Each subject needs a `fullName`; `dateOfBirth`,\r\n            `nationality`, `aliases` and `userReference` are optional. This shape carries no\r\n            per-row screening options, so every row screens under the tenant profile; for per-row option\r\n            columns, use the file-upload form instead.\r\n            \r\n\n\r\n            Each finished row emits a `screening.completed` webhook (#365), PER ROW as the processor\r\n            completes it, exactly as the file-upload path does. The same global row cap and per-tenant caps\r\n            apply.\r\n            ",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "Submit subjects as a JSON array (`application/json`) OR upload a CSV/XLSX file (`multipart/form-data`). Either way the rows queue the SAME asynchronous batch job — the response is `202 { jobId, totalRows, status }`; poll `GET /v1/screenings/batch/{jobId}`.",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/BulkScreeningSubject"
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "required": [
                  "file"
                ],
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "description": "CSV or XLSX file, one subject per row. Needs a `fullName`/`name` column OR a `First Name` + `Last Name` pair; `dateOfBirth`, `nationality`, `aliases` and `userReference` columns are optional.",
                    "format": "binary"
                  },
                  "threshold": {
                    "type": "string",
                    "nullable": true
                  },
                  "exactMatch": {
                    "type": "string",
                    "nullable": true
                  },
                  "adverseMedia": {
                    "type": "string",
                    "nullable": true
                  },
                  "monitor": {
                    "type": "string",
                    "nullable": true
                  },
                  "lists": {
                    "type": "string",
                    "nullable": true
                  },
                  "pepTiers": {
                    "type": "string",
                    "nullable": true
                  },
                  "coveragePreset": {
                    "type": "string",
                    "nullable": true
                  },
                  "maxDataAgeDays": {
                    "type": "string",
                    "nullable": true
                  },
                  "phonetic": {
                    "type": "string",
                    "nullable": true
                  },
                  "nicknames": {
                    "type": "string",
                    "nullable": true
                  },
                  "trigramFloor": {
                    "type": "string",
                    "nullable": true
                  },
                  "candidateLimit": {
                    "type": "string",
                    "nullable": true
                  },
                  "resultCap": {
                    "type": "string",
                    "nullable": true
                  },
                  "dobYearTolerance": {
                    "type": "string",
                    "nullable": true
                  },
                  "dobMismatchPenalty": {
                    "type": "string",
                    "nullable": true
                  },
                  "dobMismatchSurfacing": {
                    "type": "string",
                    "nullable": true
                  },
                  "dobMismatchHighScoreThreshold": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The subjects were ACCEPTED and queued. No row has been screened yet — the body carries only\r\n`jobId`, `totalRows` and an initial `status`. Poll\r\n`GET /v1/screenings/batch/{jobId}` for progress.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/BatchJobCreated"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchJobCreated"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchJobCreated"
                }
              }
            }
          },
          "400": {
            "description": "The array was empty or over the row cap. Nothing is screened or charged.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The credential carries no usable tenant.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      },
      "get": {
        "tags": [
          "BatchScreening"
        ],
        "summary": "List the tenant's recent batch jobs, newest first.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BatchJobStatusResponse"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BatchJobStatusResponse"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BatchJobStatusResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/screenings/batch/{jobId}": {
      "get": {
        "tags": [
          "BatchScreening"
        ],
        "summary": "Get a batch job's status + progress. This is the poll target for the 202 from the upload.",
        "description": "\n\r\n  `status` moves `pending` (parsed and stored, not yet claimed) → `running`\r\n            (a processor is screening rows) → `completed` (all rows processed) or `failed` (the job\r\n            failed as a whole). `processedRows` against `totalRows` is the progress. `completed`\r\n            does not mean every row succeeded — individual rows can still carry errors, visible in the\r\n            results.",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "description": "The job id returned by the upload's 202.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The job's current status and progress.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/BatchJobStatusResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchJobStatusResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchJobStatusResponse"
                }
              }
            }
          },
          "404": {
            "description": "No such job for this tenant.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/screenings/batch/{jobId}/results": {
      "get": {
        "tags": [
          "BatchScreening"
        ],
        "summary": "Download a batch job's per-row results (CSV by default, or `?format=json`).",
        "description": "\nReadable before the job finishes, which is a trap: every uploaded row is returned from the\r\n            moment of upload, and a row the processor has not reached yet comes back with a null\r\n            `screeningId` and `decision` — indistinguishable, on that row alone, from a screen that\r\n            produced nothing. Wait for `status: completed` (or read `summary.processedRows`) before\r\n            treating this as the answer. Each screened row carries its own `screeningId`; that screening\r\n            is a normal immutable audit record, and\r\n            `GET /v1/screenings/{id}` is the only way to read its matched entities,\r\n            `suppressedMatches` and `adverseMediaStatus` — the batch row itself is a summary\r\n            (`decision`, `riskScore`, `matchCount`). A row that failed carries an `error`\r\n            and no `screeningId`.",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "description": "The job id returned by the upload's 202.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "format",
            "in": "query",
            "description": "Defaults to `csv`; pass `json` for the JSON body.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The rows processed so far, with the job's status summary.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/BatchJobResults"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchJobResults"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/BatchJobResults"
                }
              }
            }
          },
          "404": {
            "description": "No such job for this tenant.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/screenings/batch/{jobId}/report": {
      "get": {
        "tags": [
          "BatchScreening"
        ],
        "summary": "Download a batch job's summary report as a branded PROOViD `application/pdf`: the job\r\nmetadata + progress followed by a per-row verdict table. (CSV of the same per-row data already\r\nexists at `.../results?format=csv`.) Tenant-scoped: a job that isn't the caller's tenant's\r\nis 404. `?format=pdf` is accepted for symmetry with the single-screening report and is the\r\ndefault.",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/json": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "text/json": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/branding": {
      "get": {
        "tags": [
          "Branding"
        ],
        "summary": "The calling tenant's effective branding. Tenant-scoped (API key or OIDC).",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/branding": {
      "put": {
        "tags": [
          "Branding"
        ],
        "summary": "Set a tenant's white-label branding. Admin-only.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetBrandingRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SetBrandingRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SetBrandingRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandingResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/screenings/bulk": {
      "post": {
        "tags": [
          "BulkScreening"
        ],
        "summary": "Screen a JSON array of subjects. SYNCHRONOUS — the `200` body carries every row's finished\r\nresult inline.",
        "description": "\n\r\n  <b>Synchronous, no job.</b> Every subject is screened through the same pipeline as\r\n             `POST /v1/screenings/check` before this responds, so the `200 OK` body already holds all\r\n             the results — `rows` plus a `summary` of total / screened / failed. There is no\r\n             `202`, no job id and nothing to poll. This differs from\r\n             `POST /v1/screenings/batch`, which IS asynchronous.\r\n\n\r\n  <b>Each row is a real, final screening.</b> A successful row carries its own\r\n             `screeningId`, and that screening is the same immutable audit record the single-screen\r\n             endpoint creates — fetchable in full via `GET /v1/screenings/{id}` (which is the only way to\r\n             read a row's matched entities, `suppressedMatches` and `adverseMediaStatus`; the bulk\r\n             row itself is a summary). Nothing revises a row's decision afterwards.\r\n\n\r\n  <b>Rows are isolated.</b> A row that fails to screen yields an error entry and the rest still\r\n             process, so a `200` does NOT mean every row succeeded — read `summary.failed` and the\r\n             per-row error field. Each row counts as one API screen against the tenant's quota.\r\n\n\r\n  <b>Each finished row emits a `screening.completed` webhook (#365).</b> A bulk row is a\r\n             real, final screening, so — like `POST /v1/screenings/check` and\r\n             `POST /v1/screenings/{id}/rescreen` — it raises `screening.completed`, PER ROW as each row\r\n             finishes, through the same signed envelope + durable outbox + retry. A row that FAILED to screen\r\n             raises nothing (the event means \"this row finished screening\"). The `200` body remains the\r\n             authoritative result for the caller's own request; the webhooks are for out-of-band subscribers.\r\n\n\r\n  `?format=csv` (or an `Accept: text/csv` header) returns the same results as a CSV\r\n             download instead of JSON.",
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "description": "Set to `csv` to receive the results as a CSV download.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The subjects to screen.",
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/BulkScreeningSubject"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Every row was PROCESSED and its result is in the body. Individual rows may still carry errors —\r\ncheck `summary.failed`.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/BulkScreeningResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkScreeningResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkScreeningResponse"
                }
              }
            }
          },
          "400": {
            "description": "The input was empty, malformed, or over the row cap.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The credential carries no usable tenant.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/cases": {
      "get": {
        "tags": [
          "Cases"
        ],
        "summary": "List/filter cases (newest first), paged.",
        "parameters": [
          {
            "name": "decision",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "reviewStatus",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "riskBand",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "isMatch",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "userReference",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "take",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 50
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CaseListResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseListResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseListResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/cases/export": {
      "get": {
        "tags": [
          "Cases"
        ],
        "summary": "Export of the filtered cases (regulator/audit). Same filters as the list. Defaults to\r\n            CSV (each row now also carries the top match's source + external id + a public verify URL);\r\n            with `?format=pdf` it renders a consolidated PDF \"second report\" — one section per case\r\n            with its matched-entities table incl. verify URLs (e.g. Decision=Fail → a failures report).\r\n            The CSV honours the `X-Export-Truncated: true` header at the 50k row cap; the PDF carries\r\n            its own in-document truncation note at its 500-case cap.",
        "parameters": [
          {
            "name": "decision",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "reviewStatus",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "riskBand",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "isMatch",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "userReference",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/json": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "text/json": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/cases/{id}": {
      "get": {
        "tags": [
          "Cases"
        ],
        "summary": "Full case detail: verdict, matches, disposition and note thread.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetailResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetailResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetailResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/cases/{id}/regulator-pack": {
      "get": {
        "tags": [
          "Cases"
        ],
        "summary": "Regulator pack: a self-contained bundle for one case — subject, screening verdict/scores,\r\nmatched entities, risk factors, disposition + notes, the related audit-log entries, and the\r\nwatchlist versions at screen time, stamped with a generatedAt timestamp. The same assembled\r\nbundle is returned as JSON (default), as a printable `application/pdf` document with\r\n`?format=pdf`, or as the tabular matched-entities table (screening summary denormalized\r\nonto each row) in columnar `application/vnd.apache.parquet` with `?format=parquet`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/json": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "text/json": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/cases/{id}/review": {
      "post": {
        "tags": [
          "Cases"
        ],
        "summary": "Set the reviewer disposition (logged as a system note).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReviewCaseRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ReviewCaseRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ReviewCaseRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetailResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetailResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetailResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/cases/{id}/monitor": {
      "post": {
        "tags": [
          "Cases"
        ],
        "summary": "Enrol THIS case's subject into ongoing monitoring (the \"Monitor this subject\" toggle on the case\r\ndrawer). Idempotent — re-enrolling refreshes the subject's baseline rather than duplicating.\r\nReturns the monitored subject. 409 when the tenant has ongoing monitoring switched off (enable it\r\nin Settings first); 404 when the case isn't the tenant's. Stop monitoring via\r\n`DELETE /v1/monitoring/subjects/{id}`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/MonitoredSubjectResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitoredSubjectResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitoredSubjectResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/cases/bulk": {
      "post": {
        "tags": [
          "Cases"
        ],
        "summary": "Apply one disposition (clear|confirm|escalate|reopen) to many cases at once.\r\n            Tenant-scoped: ids that aren't the tenant's are reported per-id as notFound, never failing the\r\n            whole request. Returns a per-id result in the supplied order.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkCaseActionRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkCaseActionRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/BulkCaseActionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/BulkCaseActionResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkCaseActionResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkCaseActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/cases/{id}/notes": {
      "post": {
        "tags": [
          "Cases"
        ],
        "summary": "Append a free-text case note.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddNoteRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/AddNoteRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/AddNoteRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CaseNoteResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseNoteResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseNoteResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/cases/{id}/attachments": {
      "post": {
        "tags": [
          "Cases"
        ],
        "summary": "Upload a file artifact against a case (multipart). Caps at 10 MB; 404 if the case\r\n            isn't the tenant's.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              },
              "encoding": {
                "file": {
                  "style": "form"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CaseAttachmentResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseAttachmentResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseAttachmentResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      },
      "get": {
        "tags": [
          "Cases"
        ],
        "summary": "List a case's attachment metadata (no bytes). 404 if the case isn't the tenant's.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CaseAttachmentResponse"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CaseAttachmentResponse"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CaseAttachmentResponse"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/cases/{id}/attachments/{attachmentId}": {
      "get": {
        "tags": [
          "Cases"
        ],
        "summary": "Download one attachment's bytes with its stored content-type. 404 if the\r\n            case/attachment isn't the tenant's.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "attachmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/pep-coverage/countries": {
      "get": {
        "tags": [
          "CountryCoverage"
        ],
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CountryCoverageResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CountryCoverageResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CountryCoverageResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/coverage/presets": {
      "get": {
        "tags": [
          "Coverage"
        ],
        "summary": "The ready-made coverage presets a tenant can apply.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CoveragePresetDto"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CoveragePresetDto"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CoveragePresetDto"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/coverage": {
      "get": {
        "tags": [
          "Coverage"
        ],
        "summary": "The tenant's active coverage (selected preset + resolved lists / PEP-level scope).",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/TenantCoverageDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantCoverageDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantCoverageDto"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/coverage/preset": {
      "post": {
        "tags": [
          "Coverage"
        ],
        "summary": "Apply a coverage preset as the tenant's global default (or reset to the full-scope\r\n            default when `key` is omitted / unknown).",
        "parameters": [
          {
            "name": "key",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/TenantCoverageDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantCoverageDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantCoverageDto"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/tenants/me/deceased-config": {
      "get": {
        "tags": [
          "DeceasedConfig"
        ],
        "summary": "Read the calling tenant's effective deceased-determination config: the COV-8 `hideDeceased`\r\nswitch and each COV-12 method's enabled flag + threshold (`ageOverMax.maxYears` default 110,\r\n`serviceOverMax.maxYears` default 80). Returns the documented defaults for a tenant that has\r\nnever customised it. Tenant-scoped (API key or OIDC token).",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/DeceasedConfigResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeceasedConfigResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeceasedConfigResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "DeceasedConfig"
        ],
        "summary": "Update the calling tenant's deceased-determination config. Body is the same object `GET`\r\nreturns. Thresholds are validated (`maxYears` between 1 and 200); an out-of-range value or a\r\nmissing method block is a 400. Admin-only (tenant admin scope).",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetDeceasedConfigRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SetDeceasedConfigRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SetDeceasedConfigRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/DeceasedConfigResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeceasedConfigResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeceasedConfigResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/risk-profile/decision-matrix": {
      "get": {
        "tags": [
          "DecisionMatrix"
        ],
        "summary": "Fetch a tenant's effective decision matrix plus the system default (read-only transparency).",
        "description": "TENANT ISOLATION: AMLService.API.ScopeToRouteTenantAttribute opens the ambient scope to the ROUTE\r\ntenant unconditionally — which is correct only for a cross-tenant caller (platform admin/operator,\r\nwho carries NO `tenant_id` claim). A tenant-scoped caller (analyst / auditor / support / tenant\r\nadmin / API key) carries a `tenant_id` claim, and MUST be confined to it: if the route tenant is\r\nnot their own, this 403s BEFORE the scoped read, so broadening the read policy to those roles cannot\r\nleak another tenant's matrix by changing `{id}`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/DecisionMatrixViewDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DecisionMatrixViewDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/DecisionMatrixViewDto"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "DecisionMatrix"
        ],
        "summary": "Set a tenant's decision-matrix cell overrides (MASTER / platform operator only). PUT semantics: the\r\nprovided cells replace the tenant's entire override set; an empty list resets to the posture-seeded\r\ndefault. Returns the updated view.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionMatrixWriteDto"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionMatrixWriteDto"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionMatrixWriteDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/DecisionMatrixViewDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DecisionMatrixViewDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/DecisionMatrixViewDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/demo/config": {
      "get": {
        "tags": [
          "Demo"
        ],
        "summary": "The public demo tenant's key, for zero-setup screening from a browser. Anonymous by design: the\r\ncaller is an anonymous visitor on the public playground. Returns `enabled: false` with an\r\nempty key when no demo key is configured, so the page degrades gracefully instead of firing a\r\nrequest that is guaranteed to 401.\r\n            \r\n\nThe demo key is WITHHELD only when the instance is a REAL self-hosted client appliance\r\n(AMLService.Application.Deployment.DeploymentOptions.SelfHosted — a shipped client build sets it `true`): our\r\nshared \"try it free\" acquisition key must never surface on a customer's own deployment. OUR\r\nself-host SHOWCASE (`wl.proovid.com`) deliberately KEEPS the key — the showcase's\r\nwhole purpose is to let a prospect TRY the self-hosted edition with zero setup, so it presents the\r\nappliance branding (edition badge, no marketing — via `GET /v1/ui/config`) yet still offers a\r\nready demo tenant on its playground. The commercial host is unchanged.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/DemoConfigResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DemoConfigResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/DemoConfigResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/eu/csv": {
      "get": {
        "tags": [
          "EuSanctions"
        ],
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/providers": {
      "get": {
        "tags": [
          "ExternalProviders"
        ],
        "summary": "List a tenant's configured external providers (API keys masked).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ExternalProviderResponse"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ExternalProviderResponse"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ExternalProviderResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/providers/{providerType}": {
      "put": {
        "tags": [
          "ExternalProviders"
        ],
        "summary": "Create or update a tenant's config for one provider type.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "providerType",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpsertExternalProviderRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpsertExternalProviderRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpsertExternalProviderRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalProviderResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalProviderResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExternalProviderResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable"
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      },
      "delete": {
        "tags": [
          "ExternalProviders"
        ],
        "summary": "Remove a tenant's config for one provider type.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "providerType",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/ingest/history": {
      "get": {
        "tags": [
          "Ingest"
        ],
        "summary": "Recent watchlist-refresh runs, newest first; optionally filtered to one source.",
        "parameters": [
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "take",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 50
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/IngestRunResponse"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/IngestRunResponse"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/IngestRunResponse"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/ingest/status": {
      "get": {
        "tags": [
          "IngestJob"
        ],
        "summary": "Live status of the ingest job (running / idle + last outcome).",
        "description": "Read from the AMLService.Domain.Entities.JobRun table rather than from a field on this pod, so it answers \"is an\r\ningest running ANYWHERE?\" instead of \"is one running HERE?\". The old in-memory status reported idle\r\non every pod but the one executing, which meant the answer depended on which replica the load\r\nbalancer happened to pick.\r\n\n\r\nDELIBERATELY STILL Screening.Read, while the triggers beside it moved to Platform.Operations. This\r\nendpoint STARTS NOTHING — it reads whether a job is running — and AMLService.Application.Ingest.IngestJobStatus\r\ncarries no operator identity: running / source / timings / last outcome, and nothing about WHO ran\r\nit. That is the distinction that put `GET /v1/jobs/triggerable` behind the platform policy —\r\nits payload NAMES the operator of each last run, so serving it to a tenant leaks identities across\r\nthe tenant boundary. Nothing here does. A tenant legitimately needs to know whether the corpus they\r\nscreen against is mid-refresh, so raising this to platform-only would remove a real capability to\r\nbuy no confidentiality.\r\n",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/IngestJobStatus"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IngestJobStatus"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/IngestJobStatus"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/ingest/refresh": {
      "post": {
        "tags": [
          "IngestJob"
        ],
        "summary": "Trigger an on-demand re-ingest of a source (PLATFORM OPERATOR).",
        "description": "AUTHORIZATION. This starts a DEPLOYMENT-WIDE job — an ingest rewrites the watchlist corpus that\r\nEVERY tenant screens against — so it is gated on AMLService.Infrastructure.Identity.Policies.PlatformOperations,\r\nidentically to `POST /v1/jobs/{name}/trigger`, which starts the very same\r\nAMLService.Application.Jobs.JobNames.Ingest job. It previously required only tenant `Admin`, so the boundary\r\nintroduced on that newer route could simply be walked around via this older one. A partial\r\nauthorization boundary is worse than none: it reads as protection while leaving every customer's\r\ntenant admin holding deployment-wide authority. No API key can reach this either — the API-key\r\nhandler mints only AMLService.Infrastructure.Identity.Roles.TenantService.\r\n\n\r\n202 with the queued run; 409 when a run of the ingest job is already queued or running ANYWHERE in\r\nthe deployment (the body carries that run's id and start time); 400 for an unknown source; 429 when\r\nthis operator has spent their trigger budget. The 409 is decided by the partial unique index on\r\nAMLService.Domain.Entities.JobRun, not by a check in this process — see the remarks on this controller. Never\r\nblocks on the ~50-minute ingest: the response means \"queued\", not \"finished\".\r\n\n\r\nThe 429 is now a per-operator frequency cap (the shared job-trigger rate limit, which also emits\r\n`Retry-After`) rather than the old \"one run per 30 minutes\" interval the deleted runner kept in\r\nmemory. That interval had the same defect as the flag beside it — each pod enforced its own — so a\r\nbudget the middleware enforces per principal is both honest and stricter in practice.\r\n",
        "parameters": [
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/JobRunDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobRunDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobRunDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/JobAlreadyRunningDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAlreadyRunningDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAlreadyRunningDto"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/ingest/retag": {
      "post": {
        "tags": [
          "IngestJob"
        ],
        "summary": "Trigger the fast, offline \"re-tag in place\" job (PLATFORM OPERATOR).",
        "description": "AUTHORIZATION. Like the ingest beside it, a re-tag is DEPLOYMENT-WIDE: it rewrites the stored\r\n`pep.category:*` topics on every WIKIDATA entity, which every tenant then screens against. It\r\nis therefore gated on AMLService.Infrastructure.Identity.Policies.PlatformOperations rather than tenant `Admin`.\r\nBeing fast and idempotent makes an unwanted run cheap to correct — it does not make it a TENANT's\r\ndecision to start, which is the question authorization answers.\r\n\n\r\nRecomputes every stored WIKIDATA entity's `pep.category:*` topics from the offices it already\r\nholds, using the current mapping — no ~50-minute WDQS holder re-fetch, just a bounded class-closure\r\nlookup. 202 with the queued run; 409 when a re-tag is already queued or running anywhere.\r\n\n\r\nThis shares the lease MECHANISM with the ingest but not its SLOT: a re-tag is serialised against\r\nother re-tags across every pod, and may overlap an ingest. The previous comment here claimed the two\r\ncould \"never collide\"; the flag that backed that claim was process-local, so across replicas they\r\nalways could. The pass is idempotent and only rewrites categories derived from topics the entity\r\nalready carries, so an overlapping ingest costs at worst a tag that the next run corrects.\r\n\r\nLive progress is on `GET /v1/jobs`.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/JobRunDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobRunDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobRunDto"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/JobAlreadyRunningDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAlreadyRunningDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAlreadyRunningDto"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/jobs": {
      "get": {
        "tags": [
          "Jobs"
        ],
        "summary": "All known background jobs and their current live status (state / phase / progress).",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/JobSnapshot"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/JobSnapshot"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/JobSnapshot"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/jobs/triggerable": {
      "get": {
        "tags": [
          "JobTriggers"
        ],
        "summary": "The jobs that can be triggered on demand, each with the provenance of its most recent run — who\r\nstarted it and how, when it was queued, when it started, and how it ended. This is what the operator\r\nconsole reads to show running / last-run / last-outcome and whether that run was manual or scheduled.",
        "description": "Platform-operator only, like the trigger itself — not merely because it is the trigger's companion,\r\nbut because the provenance it returns NAMES the operator who last ran each job. Serving that to\r\nevery tenant with Screening.Read would leak our operators' identities (and, on a self-hosted box,\r\nthe client's) across the tenant boundary. Tenants that only need job progress still have\r\n`GET /v1/jobs`, which carries no provenance.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TriggerableJobDto"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TriggerableJobDto"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TriggerableJobDto"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/jobs/{name}/trigger": {
      "post": {
        "tags": [
          "JobTriggers"
        ],
        "summary": "Trigger a job to run now. Platform operator only, and rate-limited.",
        "description": "Returns 202 with the queued run when accepted, and 409 with the OCCUPYING run when the job is\r\nalready going — never a queued duplicate (which would defeat the single-flight lease) and never a\r\nsilent no-op (which reads to the operator as a dead button). The 409 body carries the running run's\r\nid and start time so the console can say \"already running since HH:MM\".\r\n\n\r\nAUTHORIZATION. These jobs are DEPLOYMENT-WIDE, not tenant-scoped — a run affects every tenant's\r\ndata — so they are gated on AMLService.Infrastructure.Identity.Policies.PlatformOperations\r\n(AMLService.Infrastructure.Identity.Roles.PlatformOperator), NOT on tenant `admin`. A customer's admin, however\r\nsenior within their own tenant, is rejected here. No API key can reach this endpoint either.\r\n\n\r\nThe lease and the rate limit remain, on their own merits rather than as compensation for a broad\r\nauthorization surface: several pods still race each other, and an operator can still double-click.\r\n",
        "parameters": [
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "argument",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/JobRunDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobRunDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobRunDto"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/JobAlreadyRunningDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAlreadyRunningDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAlreadyRunningDto"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/leaders": {
      "get": {
        "tags": [
          "Leaders"
        ],
        "summary": "One row per leadership term (person × office × term), filtered + paged. Relatives are\r\n            appended when `includeRelatives=true`.",
        "parameters": [
          {
            "name": "country",
            "in": "query",
            "description": "ISO alpha-2 country codes (repeatable).",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "role",
            "in": "query",
            "description": "`head_of_state` or `head_of_government`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "`current`, `historical` or `all` (default all).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "yearFrom",
            "in": "query",
            "description": "Include terms overlapping on/after this year (defaults to 25 years back).",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "yearTo",
            "in": "query",
            "description": "Include terms overlapping on/before this year.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "includeRelatives",
            "in": "query",
            "description": "Also return each returned leader's relatives (PEP4). Default false.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Case-insensitive name search.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "prioritize",
            "in": "query",
            "description": "Order main European + BRIC countries first (the configured priority list).",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "1-based page number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "description": "Requested page size (capped by the service).",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/LeadersPage"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadersPage"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadersPage"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/leaders/export.csv": {
      "get": {
        "tags": [
          "Leaders"
        ],
        "summary": "The same filtered rows flattened to a CSV download (ignores paging — exports the full\r\n            filtered set).",
        "parameters": [
          {
            "name": "country",
            "in": "query",
            "description": "ISO alpha-2 country codes (repeatable).",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "role",
            "in": "query",
            "description": "`head_of_state` or `head_of_government`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "`current`, `historical` or `all` (default all).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "yearFrom",
            "in": "query",
            "description": "Include terms overlapping on/after this year (defaults to 25 years back).",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "yearTo",
            "in": "query",
            "description": "Include terms overlapping on/before this year.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "includeRelatives",
            "in": "query",
            "description": "Also return each returned leader's relatives (PEP4). Default false.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Case-insensitive name search.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "prioritize",
            "in": "query",
            "description": "Order main European + BRIC countries first (the configured priority list).",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "1-based page number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "description": "Requested page size (capped by the service).",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/leaders/export.pdf": {
      "get": {
        "tags": [
          "Leaders"
        ],
        "summary": "The same filtered rows as a presentable, regulator-ready PDF (person, country,\r\n            office/role, term, PEP class, and a source link per row). Capped at AMLService.API.Controllers.LeadersController.PdfRowCap rows\r\n            with a note pointing to the CSV for the full set.",
        "parameters": [
          {
            "name": "country",
            "in": "query",
            "description": "ISO alpha-2 country codes (repeatable).",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          {
            "name": "role",
            "in": "query",
            "description": "`head_of_state` or `head_of_government`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "`current`, `historical` or `all` (default all).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "yearFrom",
            "in": "query",
            "description": "Include terms overlapping on/after this year (defaults to 25 years back).",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "yearTo",
            "in": "query",
            "description": "Include terms overlapping on/before this year.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "includeRelatives",
            "in": "query",
            "description": "Also return each returned leader's relatives (PEP4). Default false.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Case-insensitive name search.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "prioritize",
            "in": "query",
            "description": "Order main European + BRIC countries first (the configured priority list).",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "1-based page number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "description": "Requested page size (capped by the service).",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/matching-profiles": {
      "get": {
        "tags": [
          "MatchingProfiles"
        ],
        "summary": "List the tenant's saved matching profiles plus the system presets.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfilesResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfilesResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfilesResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      },
      "post": {
        "tags": [
          "MatchingProfiles"
        ],
        "summary": "Create a named profile (inactive until activated).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MatchingProfileInput"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MatchingProfileInput"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MatchingProfileInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfileDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfileDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfileDto"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/matching-profiles/{profileId}": {
      "put": {
        "tags": [
          "MatchingProfiles"
        ],
        "summary": "Update a profile; if it is active, the change is applied to the live config.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "profileId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MatchingProfileInput"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/MatchingProfileInput"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/MatchingProfileInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfileDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfileDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfileDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      },
      "delete": {
        "tags": [
          "MatchingProfiles"
        ],
        "summary": "Delete a profile. The active profile cannot be deleted — switch first.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "profileId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/matching-profiles/{profileId}/activate": {
      "post": {
        "tags": [
          "MatchingProfiles"
        ],
        "summary": "Make a profile active (applies its parameters to the live config).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "profileId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfileDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfileDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfileDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/matching-profiles/reset": {
      "post": {
        "tags": [
          "MatchingProfiles"
        ],
        "summary": "Reset to one of our system presets (recall-first / balanced / precision-first).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetToPresetRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetToPresetRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ResetToPresetRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfileDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfileDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchingProfileDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/me": {
      "get": {
        "tags": [
          "Me"
        ],
        "summary": "Who am I: my tenant's id + display name, and my email (when OIDC).",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/MeResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/MeResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/monitoring/subjects": {
      "get": {
        "tags": [
          "Monitoring"
        ],
        "summary": "List the tenant's actively monitored subjects.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MonitoredSubjectResponse"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MonitoredSubjectResponse"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MonitoredSubjectResponse"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/monitoring/subjects/{id}": {
      "delete": {
        "tags": [
          "Monitoring"
        ],
        "summary": "Stop monitoring a subject.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/monitoring/config": {
      "get": {
        "tags": [
          "MonitoringConfig"
        ],
        "summary": "The tenant's current monitoring participation config.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/TenantMonitoringConfig"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantMonitoringConfig"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantMonitoringConfig"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "MonitoringConfig"
        ],
        "summary": "Toggle the tenant's monitoring participation and optional cadence override.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetMonitoringConfigRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SetMonitoringConfigRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SetMonitoringConfigRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/TenantMonitoringConfig"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantMonitoringConfig"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantMonitoringConfig"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/ofac/search": {
      "post": {
        "tags": [
          "Ofac"
        ],
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SanctionsSearchRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SanctionsSearchRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SanctionsSearchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/ofac/screen": {
      "post": {
        "tags": [
          "Ofac"
        ],
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SanctionsScreeningRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SanctionsScreeningRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SanctionsScreeningRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/opensanctions/batch": {
      "post": {
        "tags": [
          "OpenSanctions"
        ],
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpenSanctionsMatchRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/OpenSanctionsMatchRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/OpenSanctionsMatchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/OpenSanctionsMatchResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenSanctionsMatchResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpenSanctionsMatchResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/pep-coverage": {
      "get": {
        "tags": [
          "PepCoverage"
        ],
        "summary": "The PEP data-coverage matrix — published, tenant-agnostic transparency data: which FATF\r\n            categories we cover, their tier, and the live measured available-vs-ingested counts. It is the same\r\n            for every tenant and carries no tenant data, so it is served <b>anonymously</b> (the raw JSON backs\r\n            the public docs/marketing coverage story and is meant to be openly verifiable). Served instantly from\r\n            the cache the background audit keeps warm; before the first background run it returns the manifest\r\n            structure with zero counts. To force a fresh (slow) audit, POST to `/v1/pep-coverage/refresh`.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CoverageMatrixResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CoverageMatrixResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CoverageMatrixResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/pep-coverage/refresh": {
      "post": {
        "tags": [
          "PepCoverage"
        ],
        "summary": "Force a fresh coverage audit inline and return the new matrix. Slow (~20 paced WDQS COUNT\r\n            queries over large office-class closures), so it is gated on Screening.Read to prevent anonymous\r\n            abuse — ops use, e.g. right after a re-ingest. The background service also refreshes on its own timer.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CoverageMatrixResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CoverageMatrixResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CoverageMatrixResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/peps": {
      "get": {
        "tags": [
          "Peps"
        ],
        "summary": "One row per PEP entity, filtered + paged.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Case-insensitive name search (primary name + aliases).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "country",
            "in": "query",
            "description": "ISO alpha-2 country code.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "in": "query",
            "description": "Office-category slug (e.g. `minister`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "1-based page number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "description": "Requested page size (capped by the service).",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/PepsPage"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PepsPage"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/PepsPage"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/peps/export.csv": {
      "get": {
        "tags": [
          "Peps"
        ],
        "summary": "The same filtered rows flattened to a CSV download (ignores paging; capped).",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Case-insensitive name search (primary name + aliases).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "country",
            "in": "query",
            "description": "ISO alpha-2 country code.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "in": "query",
            "description": "Office-category slug (e.g. `minister`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "1-based page number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "description": "Requested page size (capped by the service).",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/peps/export.pdf": {
      "get": {
        "tags": [
          "Peps"
        ],
        "summary": "The same filtered rows as a presentable, regulator-ready PDF (capped at\r\n            AMLService.API.Controllers.PepsController.PdfRowCap rows with a note pointing to the CSV for the full set).",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Case-insensitive name search (primary name + aliases).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "country",
            "in": "query",
            "description": "ISO alpha-2 country code.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "in": "query",
            "description": "Office-category slug (e.g. `minister`).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "description": "1-based page number.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "description": "Requested page size (capped by the service).",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/privacy/subjects/{userReference}/export": {
      "get": {
        "tags": [
          "Privacy"
        ],
        "summary": "SAR / right of access: a self-contained JSON bundle of everything held for the subject.",
        "parameters": [
          {
            "name": "userReference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectExportResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectExportResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectExportResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/privacy/subjects/{userReference}/erase": {
      "post": {
        "tags": [
          "Privacy"
        ],
        "summary": "Right to erasure: anonymize the subject's PII across screenings + monitoring.",
        "parameters": [
          {
            "name": "userReference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/EraseSubjectResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EraseSubjectResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/EraseSubjectResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/privacy/subjects/{userReference}/restrict": {
      "post": {
        "tags": [
          "Privacy"
        ],
        "summary": "Restriction of processing (Art. 18): suppress further automated processing.",
        "parameters": [
          {
            "name": "userReference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectFlagResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectFlagResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectFlagResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/privacy/subjects/{userReference}/object": {
      "post": {
        "tags": [
          "Privacy"
        ],
        "summary": "Objection to processing (Art. 21): suppress further automated processing.",
        "parameters": [
          {
            "name": "userReference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectFlagResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectFlagResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectFlagResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/privacy/subjects/{userReference}/rectify": {
      "post": {
        "tags": [
          "Privacy"
        ],
        "summary": "Rectification (Art. 16): update the latest screening's stored subject snapshot.",
        "parameters": [
          {
            "name": "userReference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RectifySubjectRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/RectifySubjectRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/RectifySubjectRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/RectifySubjectResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RectifySubjectResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/RectifySubjectResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/privacy/consent": {
      "post": {
        "tags": [
          "Privacy"
        ],
        "summary": "Record consent: stores the exact versioned copy the subject agreed to.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordConsentRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordConsentRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/RecordConsentRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ConsentResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConsentResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConsentResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/privacy/subjects/{userReference}/consent": {
      "get": {
        "tags": [
          "Privacy"
        ],
        "summary": "Consent history for a subject (newest first).",
        "parameters": [
          {
            "name": "userReference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ConsentHistoryResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConsentHistoryResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConsentHistoryResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/privacy/subjects/{userReference}/consent/withdraw": {
      "post": {
        "tags": [
          "Privacy"
        ],
        "summary": "Withdraw the subject's active consents (Art. 7(3)); keeps the proof trail.",
        "parameters": [
          {
            "name": "userReference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/WithdrawConsentResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WithdrawConsentResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/WithdrawConsentResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/quota": {
      "put": {
        "tags": [
          "Quota"
        ],
        "summary": "Set (or clear) a tenant's monthly screening quota. Admin-only.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetQuotaRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SetQuotaRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SetQuotaRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/rate-limit": {
      "put": {
        "tags": [
          "Quota"
        ],
        "summary": "Set (or clear) a tenant's per-minute screening rate limit. Admin-only.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetRateLimitRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SetRateLimitRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SetRateLimitRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/demo-ip-rate-limit": {
      "put": {
        "tags": [
          "Quota"
        ],
        "summary": "Set (or clear) the demo tenant's per-IP screening cap (per hour). Admin-only. Only\r\n            meaningful on the shared public demo tenant; a null/absent value disables the per-IP demo cap.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetDemoIpRateLimitRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SetDemoIpRateLimitRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SetDemoIpRateLimitRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/batch-config": {
      "put": {
        "tags": [
          "Quota"
        ],
        "summary": "Set (or clear) a tenant's per-batch-upload row cap. Admin-only. A null/absent value\r\n            leaves batch uploads unlimited (bounded only by the global engine cap).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetBatchConfigRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SetBatchConfigRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SetBatchConfigRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/credits": {
      "put": {
        "tags": [
          "Quota"
        ],
        "summary": "Top up a tenant's credit balance and/or set its per-screen cost. Admin-only.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetCreditsRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SetCreditsRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SetCreditsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/sanctions-policy": {
      "put": {
        "tags": [
          "Quota"
        ],
        "summary": "Set a tenant's UNCONFIRMED-sanctions decision posture. Admin-only. `\"Review\"` (default) sends a\r\nno-DOB partial-name sanctions overlap to human review; `\"Fail\"` (strict) auto-rejects it. A\r\nconfirmed (exact full-DOB) sanctions hit always fails regardless of this setting.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetSanctionsPolicyRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SetSanctionsPolicyRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SetSanctionsPolicyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/SanctionsPolicyResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SanctionsPolicyResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/SanctionsPolicyResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/usage": {
      "get": {
        "tags": [
          "Quota"
        ],
        "summary": "The calling tenant's current-month screening usage. Tenant-scoped (API key or OIDC).",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuotaUsageResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/register": {
      "post": {
        "tags": [
          "Register"
        ],
        "summary": "Provision a sandbox trial tenant + test API key. Returns the key once.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/RegisterResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegisterResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegisterResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tenants/{id}/risk-profile": {
      "get": {
        "tags": [
          "RiskProfiles"
        ],
        "summary": "Fetch a tenant's risk profile.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/RiskProfileDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RiskProfileDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/RiskProfileDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "RiskProfiles"
        ],
        "summary": "Replace a tenant's risk profile.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RiskProfileDto"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/RiskProfileDto"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/RiskProfileDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/RiskProfileDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RiskProfileDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/RiskProfileDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/risk-profile/coverage-presets": {
      "get": {
        "tags": [
          "RiskProfiles"
        ],
        "summary": "The ready-made coverage presets the tenant can apply (for the console picker).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CoveragePresetDto"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CoveragePresetDto"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CoveragePresetDto"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/risk-profile/coverage-preset": {
      "post": {
        "tags": [
          "RiskProfiles"
        ],
        "summary": "Apply a coverage preset (lists + PEP-level scope + decision policy) to the tenant, or\r\n            reset to the full-scope default. `key` omitted / unknown resets to `comprehensive`.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "key",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/RiskProfileDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RiskProfileDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/RiskProfileDto"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/screenings/check": {
      "post": {
        "tags": [
          "Screening"
        ],
        "summary": "Screen one subject against the registered providers and return the finished result.\r\nSYNCHRONOUS — the `201` body is the complete outcome, not an acknowledgement.",
        "description": "\n\r\n  <b>Fully synchronous.</b> A single request runs the ENTIRE pipeline inline — provider\r\n             fan-out, classification, post-screening validation, risk scoring and persistence — and responds\r\n             `201 Created` carrying the complete screening result, plus a `Location` header pointing\r\n             at `GET /v1/screenings/{id}`. There is no `202 Accepted`, no job identifier to poll, and\r\n             no `PROCESSING` / `PENDING` / `IN_PROGRESS` state anywhere in the response: if you\r\n             hold the `201` you hold the verdict. Budget for the latency of the work itself rather than of\r\n             an enqueue, and set client timeouts accordingly.\r\n\n\r\n  <b>The result is final.</b> A screening is an immutable audit record of what the watchlists\r\n             said at that instant. No background process ever revises its `decision`, `riskScore`,\r\n             `riskBand`, `classification` or matched entities — re-reading it later via\r\n             `GET /v1/screenings/{id}` returns the same verdict. The only fields that change afterwards are\r\n             the human disposition overlay written by an analyst (`reviewStatus`, `reviewedBy`,\r\n             `reviewedAt`, `reviewReason`), and the record can eventually be removed by the tenant's\r\n             data-retention purge. Re-evaluating the same subject against the CURRENT lists is a NEW screening —\r\n             `POST /v1/screenings/{id}/rescreen` — which leaves the original untouched.\r\n\n\r\n  <b>The `screening.completed` webhook mirrors this response; it does not extend it.</b>\r\n             When the tenant has a subscribed endpoint, the event is projected from this very response object\r\n             through one shared factory, so the webhook and the `201` body cannot disagree about\r\n             `decision`, `riskScore` or classification. It is handed to a durable outbox and delivered\r\n             OFF the request path, so it is never a prerequisite of the `201` and carries nothing the\r\n             `201` did not already tell you. Treat the `201` body as authoritative for your own call —\r\n             do not block on a callback to confirm a result you are already holding — and use webhooks for state\r\n             you did not ask for, chiefly\r\n             `monitoring.alert`, raised when a subject enrolled with `monitor: true` later changes\r\n             outcome on a watchlist update.\r\n\n\r\n  <b>The webhook's `matchCount` counts VISIBLE matches only.</b> It is the length of\r\n             `matchedEntities` — the matches that actually drove the decision. Matches hidden by the\r\n             tenant's deceased-suppression policy are NOT added into it, because the decision excluded them too;\r\n             they are returned separately on this synchronous response as `suppressedMatches` with the count\r\n             in `suppressedDeceasedCount`, and they appear nowhere in the webhook. A receiver reconciling a\r\n             webhook against a fetched screening must compare `matchCount` with `matchedEntities`,\r\n             never with `matchedEntities + suppressedMatches`.\r\n\n\r\n  <b>\r\n    `adverseMediaStatus` is a \"did we look?\" field, not a result.</b>\r\n  `Skipped` — the caller opted out or the feature is off; we did not look.\r\n             `Ok` — the source answered (or a fresh cache was reused); an empty media result here genuinely\r\n             means clean.\r\n             `Stale` — the source was unavailable and a previously cached lookup was served; the evidence\r\n             may be out of date.\r\n             `Unavailable` — the source was unavailable and there was no cache, so ADVERSE MEDIA WAS NOT\r\n             CHECKED. `Unavailable` is NOT a clean result and must never be read as one; a caller whose\r\n             policy depends on adverse media should treat it as an incomplete screen and retry.\r\n\n\r\n  <b>Idempotency and event de-duplication.</b> Supplying an `Idempotency-Key` header makes\r\n             a repeat of the same call REPLAY: the original screening is returned rather than re-run, and no new\r\n             screening is created. A replay still emits `screening.completed`, carrying the ORIGINAL\r\n             `screeningId` — so the same `screeningId` can legitimately arrive more than once.\r\n             `POST /v1/screenings/{id}/rescreen` emits the SAME event type with a NEW `screeningId`, so\r\n             the event type alone tells a receiver nothing about which of the two happened. Receivers must\r\n             de-duplicate on the delivery's event id (`X-AML-Event-Id`), not on the event type and not on\r\n             the screening id.\r\n\n\r\n  <b>Other entry points.</b> Many subjects in one synchronous call:\r\n             `POST /v1/screenings/bulk` (`200 OK`, every row inline). Large files:\r\n             `POST /v1/screenings/batch`, the only asynchronous route (`202 Accepted` + a job id to\r\n             poll).",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "description": "Optional `Idempotency-Key`. A repeat with the same key replays the original screening instead\r\nof running a new one, and re-emits `screening.completed` with the original `screeningId`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "description": "The subject to screen, or a `subjectId` naming a registered subject.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScreeningCheckRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ScreeningCheckRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ScreeningCheckRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The screening COMPLETED. The body is the final result — decision, risk score and matches — and the\r\n`Location` header points at the persisted record. Nothing further needs to be polled or awaited.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ScreeningResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScreeningResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScreeningResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request body failed validation.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "402": {
            "description": "Out of pre-paid screening credits (pay-per-screen tenants).",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The credential carries no usable tenant.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "A `subjectId` was supplied that this tenant has no such subject for. Deliberately never 403 —\r\nthat would confirm the id exists under another tenant.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Per-minute rate limit, per-IP demo cap, or the monthly quota. Honour `Retry-After` where present.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/screenings/{id}/rescreen": {
      "post": {
        "tags": [
          "Screening"
        ],
        "summary": "Re-screen a previously persisted screening against the CURRENT watchlists, persisting a fresh\r\nresult. SYNCHRONOUS, like `POST /v1/screenings/check`.",
        "description": "\nReloads the original's subject snapshot (name / DOB / nationality / aliases / requested\r\n             lists) and runs it through the SAME orchestrator against today's watchlists and the tenant's\r\n             current configuration. The re-screen counts like a normal API screen (source `api`), so it\r\n             passes the same rate / quota / credit gates.\r\n\n\r\n  <b>Synchronous and final, on the same terms as `/screenings/check`.</b> The whole\r\n             pipeline runs inline and the `201` body is the complete outcome — no job, nothing to poll.\r\n             The result is a NEW immutable screening with its own id; the original is left exactly as it was,\r\n             including its analyst disposition.\r\n\n\r\n  <b>Emits `screening.completed` with a NEW `screeningId`.</b> A re-screen and a\r\n             fresh screen produce the same event type from the same shared factory, so a receiver cannot tell\r\n             them apart by event type — and an idempotent REPLAY of `/screenings/check` emits that type\r\n             carrying an ALREADY-SEEN `screeningId`. De-duplicate on the delivery's event id\r\n             (`X-AML-Event-Id`).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The screening to re-run. Tenant-scoped; another tenant's id is 404.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "The re-screen COMPLETED. The body is the final result of a NEW screening with a new id; the\r\noriginal screening is unchanged.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ScreeningResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScreeningResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScreeningResponse"
                }
              }
            }
          },
          "402": {
            "description": "Out of pre-paid screening credits — a re-screen is billed like any screen.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "The credential carries no usable tenant.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No such screening for this tenant.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Per-minute rate limit or the monthly quota. Honour `Retry-After` where present.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/screenings/{id}": {
      "get": {
        "tags": [
          "Screening"
        ],
        "summary": "Fetch a previously persisted screening (tenant-scoped).",
        "description": "\nReturns the SAME shape `POST /v1/screenings/check` returned, from the same mapper. This\r\n            is a read of an immutable audit record, not a poll: the verdict never changes between the original\r\n            `201` and any later read, so there is no state to wait for here. What CAN differ from the\r\n            original response is the analyst disposition overlay, and `tenantDeceasedConfig`, which always\r\n            echoes the tenant's CURRENT deceased-determination configuration rather than the one in force when\r\n            the screen ran.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "The screening id. Another tenant's id is 404, never 403.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The stored screening — the same final result the original call returned.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ScreeningResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScreeningResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScreeningResponse"
                }
              }
            }
          },
          "403": {
            "description": "The credential carries no usable tenant.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "No such screening for this tenant.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/screenings/{id}/report": {
      "get": {
        "tags": [
          "Screening"
        ],
        "summary": "Download a screening's \"Match Details Report\": a branded PROOViD document summarising the\r\nscreened subject, the search settings, the verdict + risk scoring, and the matched entities.\r\n`?format=pdf` returns a printable `application/pdf`; `?format=csv` (the default\r\nwhen omitted) returns a flat `text/csv` with the verdict denormalized onto one row per\r\nmatch. Tenant-scoped: a screening that isn't the caller's tenant's is 404 (never leaked).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/json": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "text/json": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/lists/version": {
      "get": {
        "tags": [
          "Screening"
        ],
        "summary": "Version map of the ingested watchlists, keyed by source list.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "$ref": "#/components/schemas/ListVersionResponse"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "$ref": "#/components/schemas/ListVersionResponse"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": {
                    "$ref": "#/components/schemas/ListVersionResponse"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/screenings/search": {
      "get": {
        "tags": [
          "ScreeningSearch"
        ],
        "summary": "Full-text search over screenings (subject FullName + Aliases + UserReference + matched entity\r\nnames), ranked by ts_rank then newest-first. Optional decision / date-range filters and paging.\r\nSupply `userReference` for an EXACT-match filter (WI-370): unlike the ranked substring\r\nbehaviour of `q`, it returns only the screenings whose reference equals the value exactly, so\r\nan integrator can deterministically retrieve every check they logged for one of their users.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "decision",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "userReference",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 0
            }
          },
          {
            "name": "take",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32",
              "default": 50
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ScreeningSearchResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScreeningSearchResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScreeningSearchResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/admin/stats": {
      "get": {
        "tags": [
          "Stats"
        ],
        "summary": "Aggregated platform statistics (watchlists, screenings, tenants).",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/StatsResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatsResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatsResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/subjects": {
      "post": {
        "tags": [
          "Subjects"
        ],
        "summary": "Register a subject so it can be screened by id.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubjectRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SubjectRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SubjectRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      },
      "get": {
        "tags": [
          "Subjects"
        ],
        "summary": "List the tenant's registered subjects, newest first.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SubjectResponse"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SubjectResponse"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SubjectResponse"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/subjects/{id}": {
      "get": {
        "tags": [
          "Subjects"
        ],
        "summary": "One registered subject. 404 when unknown OR owned by another tenant.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "Subjects"
        ],
        "summary": "Replace a subject's identity (full replace — an omitted optional field clears it). Past\r\nscreenings are untouched: they hold their own snapshot of what was screened and carry no\r\nforeign key back to the subject, so a correction cannot rewrite the record of what was checked.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubjectRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SubjectRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SubjectRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      },
      "delete": {
        "tags": [
          "Subjects"
        ],
        "summary": "Remove a registered subject. Past screenings SURVIVE — they are the compliance record. This is\r\nnot a GDPR erasure; see the class remarks.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/tenants": {
      "post": {
        "tags": [
          "Tenants"
        ],
        "summary": "The one call: provisions tenant + API key + risk profile + webhook in one shot.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OnboardTenantRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/OnboardTenantRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/OnboardTenantRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardTenantResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardTenantResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardTenantResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      },
      "get": {
        "tags": [
          "Tenants"
        ],
        "summary": "All tenants with their current limits + this month's usage. Admin-only — powers the\r\n            master's tenant-limits console. Quota/rate null = unlimited.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}": {
      "get": {
        "tags": [
          "Tenants"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/status": {
      "put": {
        "tags": [
          "Tenants"
        ],
        "summary": "Enable or disable a tenant. Disabling blocks its API keys (auth) and cascades to\r\n            deactivate all its console login users; enabling reverses both. Admin-only.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetTenantStatusRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SetTenantStatusRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SetTenantStatusRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/monitoring": {
      "get": {
        "tags": [
          "Tenants"
        ],
        "summary": "Read a tenant's ongoing-monitoring participation config. Admin-only.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      },
      "put": {
        "tags": [
          "Tenants"
        ],
        "summary": "Toggle a tenant's monitoring participation + optional cadence override. Admin-only.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetMonitoringConfigRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SetMonitoringConfigRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SetMonitoringConfigRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/webhooks": {
      "post": {
        "tags": [
          "Tenants"
        ],
        "summary": "Register a webhook endpoint for a tenant (signing secret shown once). Admin-only.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      },
      "get": {
        "tags": [
          "Tenants"
        ],
        "summary": "List a tenant's webhook endpoints (secrets never returned). Admin-only.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/webhooks/{webhookId}": {
      "delete": {
        "tags": [
          "Tenants"
        ],
        "summary": "Delete one of a tenant's webhook endpoints. Admin-only.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/api-keys": {
      "post": {
        "tags": [
          "Tenants"
        ],
        "summary": "Mint an API key for a tenant. `live=true` (the default) issues a production\r\n`aml_live_` key; `live=false` issues a non-billable sandbox `aml_test_` key, which\r\nis how a tenant (or our own E2E suite) gets a credential that is safely distinguishable from a\r\nproduction one. Admin-only — a live key is only ever minted by a human.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "label",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "live",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/IssuedApiKey"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssuedApiKey"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/IssuedApiKey"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/api-keys/{keyId}": {
      "delete": {
        "tags": [
          "Tenants"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "keyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      }
    },
    "/v1/threshold/events": {
      "post": {
        "tags": [
          "Threshold"
        ],
        "summary": "Record a turnover event for a subject and recompute its rolling-window turnover. When the sum\r\ncrosses the tenant's threshold, an enhanced re-screen is auto-triggered (its id is returned in\r\n`rescreenId`); if the subject was never screened, the breach is recorded and the\r\nauto-screen skipped with a reason.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordTurnoverEventRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordTurnoverEventRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/RecordTurnoverEventRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/TurnoverEventResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TurnoverEventResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/TurnoverEventResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/threshold/subjects/{subjectReference}": {
      "get": {
        "tags": [
          "Threshold"
        ],
        "summary": "Current rolling-turnover ledger status for a subject.",
        "parameters": [
          {
            "name": "subjectReference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ThresholdSubjectResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThresholdSubjectResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThresholdSubjectResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/tenants/{id}/threshold-config": {
      "put": {
        "tags": [
          "ThresholdConfig"
        ],
        "summary": "Set (or clear, with a null threshold) a tenant's turnover-threshold config. Admin-only.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetThresholdConfigRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SetThresholdConfigRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SetThresholdConfigRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ThresholdConfigResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThresholdConfigResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThresholdConfigResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          },
          "403": {
            "description": "Authenticated, but the caller's role does not satisfy the endpoint's policy."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          }
        ]
      },
      "get": {
        "tags": [
          "ThresholdConfig"
        ],
        "summary": "Read a tenant's turnover-threshold config. Tenant-scoped (the caller reads its own).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ThresholdConfigResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThresholdConfigResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ThresholdConfigResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/ui/config": {
      "get": {
        "tags": [
          "Ui"
        ],
        "summary": "The bundled UI's runtime configuration. Anonymous by design: the caller is an anonymous visitor on\r\na public bundled page, and no value here is a secret.",
        "parameters": [
          {
            "name": "X-Forwarded-Host",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/UiConfigResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UiConfigResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/UiConfigResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/watchlists/health": {
      "get": {
        "tags": [
          "WatchlistHealth"
        ],
        "summary": "Per-source health summary for the shared corpus — sanctions sources (UN/EU/OFAC/UK) escalate\r\n            to Alert when stale or failing; other sources to Warn. Thresholds are configurable (WatchlistHealth\r\n            section).",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/WatchlistHealthResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WatchlistHealthResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/WatchlistHealthResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/admin/watchlists/ingest": {
      "post": {
        "tags": [
          "WatchlistsAdmin"
        ],
        "summary": "Trigger a re-ingestion of a source list. (Equivalent to `POST /v1/ingest/refresh`.)",
        "description": "Queues a run and returns 202 immediately — a full ingest is ~50 minutes and must not block the\r\nrequest. 409 when a run of the ingest job is already queued or running ANYWHERE in the deployment;\r\n429 when this operator has spent their trigger budget.\r\n\n\r\nThe 409 comes from the partial unique index on `JobRuns`, so it holds across replicas. It\r\npreviously came from a `bool` field on a per-process singleton, which could only ever answer\r\nfor the pod that happened to serve the request — meaning two pods each returned 202 and each started\r\na ~50-minute WDQS-heavy pass. See AMLService.API.Controllers.IngestJobController for the full account.\r\n\n\r\nAUTHORIZATION, AND WHAT IT BREAKS. This is the same AMLService.Application.Jobs.JobNames.Ingest job that\r\n`POST /v1/jobs/{name}/trigger` starts, so it carries the same\r\nAMLService.Infrastructure.Identity.Policies.PlatformOperations requirement. It previously accepted tenant `Admin`,\r\nwhich made the platform boundary on the newer route bypassable by URL choice.\r\n\n\r\nThis is a BREAKING CHANGE for one shipped caller: the optional `aml-ingest-cron` sidecar\r\n(`deploy/ingest-cron/ingest-loop.sh`, compose profile `ingest`) drives this route with an\r\n`aml-admin-cli` client-credentials token, and that client is registered with\r\n`Roles: [\"admin\"]` only — so it now receives 403. Corpus freshness does NOT depend on it: the\r\nsupported path is the in-process AMLService.Infrastructure.Watchlists.WatchlistIngestionHostedService\r\n(`Ingestion__Enabled=true`, set in both the k8s deployment and the standalone env example),\r\nwhich queues its runs through `JobTriggerService` directly, over no HTTP and with no token, and\r\nis therefore untouched by this policy. The cron is opt-in, commented out by default, and already\r\ndocumented as the discouraged path. An operator who nevertheless relies on it must grant\r\nAMLService.Infrastructure.Identity.Roles.PlatformOperator to the client it authenticates as.\r\n",
        "parameters": [
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/JobRunDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobRunDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobRunDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/JobAlreadyRunningDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAlreadyRunningDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAlreadyRunningDto"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/webhooks/receiver": {
      "post": {
        "tags": [
          "WebhookCapture"
        ],
        "summary": "Create the tenant's capture bin, or rotate its token if one already exists. The token is\r\nreturned ONCE — it is the sole credential on an anonymous POST endpoint, so only its hash is\r\nstored and it cannot be recovered later.\r\n\n\r\nRotation deletes the captures taken under the previous token: they were addressed by a\r\ncredential the tenant has just declared burnt.\r\n",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedWebhookCaptureBinDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedWebhookCaptureBinDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedWebhookCaptureBinDto"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      },
      "get": {
        "tags": [
          "WebhookCapture"
        ],
        "summary": "The tenant's capture bin metadata (never the token). 404 when they have not created one.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookCaptureBinDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookCaptureBinDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookCaptureBinDto"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/webhooks/receiver/captures": {
      "get": {
        "tags": [
          "WebhookCapture"
        ],
        "summary": "What arrived at the tenant's bin, newest first: headers, body, timestamp, and the signature\r\nverdict (`verified` / `mismatch` / `missing` / `unverifiable`). On a\r\nmismatch the response also carries the signature WE compute, which is the comparison a client\r\ndebugging their own verifier actually needs.\r\n\n\r\n🔴 `body`, `headers` and `signatureHeader` are UNTRUSTED text chosen by whoever\r\nheld the token. Clients MUST render them as inert text — never as HTML/markdown, never evaluated.\r\n",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookCaptureDto"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookCaptureDto"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookCaptureDto"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      },
      "delete": {
        "tags": [
          "WebhookCapture"
        ],
        "summary": "Delete all of the tenant's captures — the \"clear the bin before I retest\" action.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/webhooks/receiver/{token}": {
      "post": {
        "tags": [
          "WebhookCapture"
        ],
        "summary": "The capture sink itself: accepts any webhook POST and records it against the bin the token\r\nidentifies.",
        "description": "Anonymous by necessity — the sender is a webhook client, which has no bearer token. The path\r\ntoken is the credential.\r\n\n\r\n🔴 The response is a fixed `202` with a constant body whether the token is valid, expired,\r\nmalformed or entirely made up. Returning 404 for an unknown token would turn this into an\r\noracle that confirms live capture URLs one guess at a time.\r\n\n\r\nThe body is read through a bounded reader: at most\r\nAMLService.Application.Webhooks.WebhookCaptureLimits.MaxReadChars characters are pulled off the wire, so a\r\nhostile sender cannot make us buffer an unbounded upload, and anything past the stored cap is\r\nrecorded as explicitly truncated rather than silently lost.\r\n",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted"
          }
        }
      }
    },
    "/v1/webhooks": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Register a webhook endpoint. The signing secret is returned ONCE — store it to verify\r\n            delivery signatures. Tenant-scoped.",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedWebhookDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedWebhookDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreatedWebhookDto"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      },
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "The tenant's registered webhook endpoints (secrets never returned).",
        "parameters": [
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookEndpointDto"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookEndpointDto"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookEndpointDto"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/webhooks/{id}": {
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Delete one of the tenant's webhook endpoints.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/webhooks/{id}/test": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Send a signed `webhook.test` event to one of the tenant's endpoints and return what the\r\nendpoint answered. Uses the SAME signature scheme, headers and per-endpoint secret as a real\r\n`screening.completed`, so a receiver that verifies this verifies production traffic — without\r\nhaving to run a real screening against a real person first.\r\n\n\r\nUnlike production events this delivery is synchronous and is NOT retried: the point is to report\r\nthe receiver's state right now. A non-2xx from the receiver is still a `200` from us, carrying\r\n`success:false` and the status code — the call succeeded, the delivery did not.\r\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookTestResultDto"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookTestResultDto"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookTestResultDto"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    },
    "/v1/webhooks/deliveries": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "The tenant's most recent webhook delivery attempts (newest first, last 7 days) — the self-serve\r\nanswer to \"are my webhooks working, and if not, why?\".\r\n\n\r\nEach attempt reports what the receiver actually returned (`statusCode` plus a bounded prefix\r\nof its `responseBody`), which attempt it was, when it will next be retried, and whether the\r\nretry budget was exhausted (`deadLettered`) — so a permanently lost event is visible here\r\nrather than only in an in-cluster log.\r\n\n`responseBody` is UNTRUSTED text chosen by the tenant's own (arbitrary) receiver URL. Clients\r\nMUST render it as inert text — never as HTML/markdown, never evaluated.\r\n\nOptionally filter to failures only with `?failedOnly=true` when triaging an incident.",
        "parameters": [
          {
            "name": "failedOnly",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "X-Correlation-Id",
            "in": "header",
            "description": "Optional tracing key for this call. Supply your own value to correlate this request with your own systems — it is echoed back on the X-Correlation-Id response header AND in the response body (correlationId), and carried on the screening.completed webhook, so a delivered webhook can be tied back to the call that produced it. Omit it and the service generates one for you.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookDeliveryDto"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookDeliveryDto"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookDeliveryDto"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated — credential missing, malformed, expired, or revoked."
          }
        },
        "security": [
          {
            "OpenIdConnect": [ ]
          },
          {
            "ApiKey": [ ]
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "AddNoteRequest": {
        "type": "object",
        "properties": {
          "body": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "Address": {
        "type": "object",
        "properties": {
          "address1": {
            "type": "string",
            "nullable": true
          },
          "address2": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "stateOrProvince": {
            "type": "string",
            "nullable": true
          },
          "postalCode": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AddressDto": {
        "type": "object",
        "properties": {
          "address1": {
            "type": "string",
            "nullable": true
          },
          "address2": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "stateOrProvince": {
            "type": "string",
            "nullable": true
          },
          "postalCode": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AgeOverMaxMethodConfig": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "maxYears": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Method 2 (`age_over_max`, presumed): on/off + the age ceiling in years."
      },
      "AuditEntryResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "actor": {
            "type": "string",
            "nullable": true
          },
          "action": {
            "type": "string",
            "nullable": true
          },
          "targetType": {
            "type": "string",
            "nullable": true
          },
          "targetId": {
            "type": "string",
            "nullable": true
          },
          "metadata": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "One audit-trail row."
      },
      "AuditListResponse": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AuditEntryResponse"
            },
            "nullable": true
          },
          "total": {
            "type": "integer",
            "format": "int32"
          },
          "skip": {
            "type": "integer",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "A page of audit entries plus the total count for the filter."
      },
      "AuditVerifyResponse": {
        "type": "object",
        "properties": {
          "entries": {
            "type": "integer",
            "description": "Number of entries walked (those carrying a hash; legacy null-hash rows are skipped).",
            "format": "int32"
          },
          "valid": {
            "type": "boolean",
            "description": "True when every walked entry's recomputed hash matches what was persisted."
          },
          "firstBrokenId": {
            "type": "string",
            "description": "The first entry whose hash didn't match, or null when the chain is intact.",
            "format": "uuid",
            "nullable": true
          },
          "skippedLegacy": {
            "type": "integer",
            "description": "Leading legacy rows (no hash) that were skipped before the chain begins.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Result of verifying the tenant's tamper-evident audit hash chain."
      },
      "BatchJobCreated": {
        "type": "object",
        "properties": {
          "jobId": {
            "type": "string",
            "format": "uuid"
          },
          "totalRows": {
            "type": "integer",
            "format": "int32"
          },
          "status": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "202-Accepted body returned when a batch upload is accepted for processing."
      },
      "BatchJobResults": {
        "type": "object",
        "properties": {
          "summary": {
            "$ref": "#/components/schemas/BatchJobStatusResponse"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BatchJobRowResult"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Full results of a batch job: the status summary plus the per-row results."
      },
      "BatchJobRowResult": {
        "type": "object",
        "properties": {
          "rowIndex": {
            "type": "integer",
            "format": "int32"
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "userReference": {
            "type": "string",
            "nullable": true
          },
          "screeningId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "isMatch": {
            "type": "boolean"
          },
          "decision": {
            "type": "string",
            "nullable": true
          },
          "riskScore": {
            "type": "integer",
            "format": "int32"
          },
          "matchCount": {
            "type": "integer",
            "format": "int32"
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "#376: explicit lifecycle state — `pending` / `complete` /\r\n            `failed` — so an UNPROCESSED row is distinguishable from a CLEAN result without inference. See\r\n            AMLService.Application.Batch.BatchRowStatus.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One row in a batch job's results (GET .../results)."
      },
      "BatchJobStatusResponse": {
        "type": "object",
        "properties": {
          "jobId": {
            "type": "string",
            "format": "uuid"
          },
          "fileName": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "totalRows": {
            "type": "integer",
            "format": "int32"
          },
          "processedRows": {
            "type": "integer",
            "format": "int32"
          },
          "matchedRows": {
            "type": "integer",
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Status + progress of a batch job (GET /v1/screenings/batch/{jobId})."
      },
      "BatchUploadOptionsForm": {
        "type": "object",
        "properties": {
          "threshold": {
            "type": "string",
            "nullable": true
          },
          "exactMatch": {
            "type": "string",
            "nullable": true
          },
          "adverseMedia": {
            "type": "string",
            "nullable": true
          },
          "monitor": {
            "type": "string",
            "nullable": true
          },
          "lists": {
            "type": "string",
            "nullable": true
          },
          "pepTiers": {
            "type": "string",
            "nullable": true
          },
          "coveragePreset": {
            "type": "string",
            "nullable": true
          },
          "maxDataAgeDays": {
            "type": "string",
            "nullable": true
          },
          "phonetic": {
            "type": "string",
            "nullable": true
          },
          "nicknames": {
            "type": "string",
            "nullable": true
          },
          "trigramFloor": {
            "type": "string",
            "nullable": true
          },
          "candidateLimit": {
            "type": "string",
            "nullable": true
          },
          "resultCap": {
            "type": "string",
            "nullable": true
          },
          "dobYearTolerance": {
            "type": "string",
            "nullable": true
          },
          "dobMismatchPenalty": {
            "type": "string",
            "nullable": true
          },
          "dobMismatchSurfacing": {
            "type": "string",
            "nullable": true
          },
          "dobMismatchHighScoreThreshold": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The JOB-level screening options a caller may send alongside the uploaded file, as multipart form\r\nfields — the defaults every row of the file screens under, unless the row's own option columns say\r\notherwise. Every field of AMLService.Application.Screening.ScreeningOptions is settable here, so a batch has FULL option\r\nparity with a single screen even for the options that make no sense to vary row by row."
      },
      "BrandingResponse": {
        "type": "object",
        "properties": {
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "logoUrl": {
            "type": "string",
            "nullable": true
          },
          "accentColor": {
            "type": "string",
            "nullable": true
          },
          "theme": {
            "$ref": "#/components/schemas/BrandingTheme"
          }
        },
        "additionalProperties": false,
        "description": "A tenant's white-label branding. AMLService.Application.Branding.BrandingResponse.DisplayName falls back to the tenant name;\r\nAMLService.Application.Branding.BrandingResponse.LogoUrl and AMLService.Application.Branding.BrandingResponse.AccentColor are null when unset (the consuming UI keeps\r\nits own defaults). AMLService.Application.Branding.BrandingResponse.AccentColor is also mirrored inside AMLService.Application.Branding.BrandingResponse.Theme — it\r\nstays at the top level for back-compat with existing readers."
      },
      "BrandingTheme": {
        "type": "object",
        "properties": {
          "accentColor": {
            "type": "string",
            "nullable": true
          },
          "secondaryColor": {
            "type": "string",
            "nullable": true
          },
          "surfaceColor": {
            "type": "string",
            "nullable": true
          },
          "textColor": {
            "type": "string",
            "nullable": true
          },
          "fontFamily": {
            "type": "string",
            "nullable": true
          },
          "cornerRadius": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The design-token bundle a frontend maps onto CSS custom properties. Each token is null when the\r\ntenant hasn't set it; AMLService.Application.Branding.BrandingTheme.AccentColor equals AMLService.Application.Branding.BrandingResponse.AccentColor."
      },
      "BulkCaseActionItemResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One id's outcome. AMLService.Application.Cases.BulkCaseActionItemResult.Error is set only when AMLService.Application.Cases.BulkCaseActionItemResult.Status is \"error\"."
      },
      "BulkCaseActionRequest": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "nullable": true
          },
          "action": {
            "type": "string",
            "description": "One of clear|confirm|escalate|reopen (see AMLService.Application.Cases.BulkCaseActions).",
            "nullable": true
          },
          "note": {
            "type": "string",
            "description": "Optional reason recorded with each disposition.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Apply one disposition to many cases in a single tenant-scoped request."
      },
      "BulkCaseActionResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkCaseActionItemResult"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The per-id results of a bulk action, in the order the ids were supplied."
      },
      "BulkScreeningResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkScreeningRowResult"
            },
            "nullable": true
          },
          "summary": {
            "$ref": "#/components/schemas/BulkScreeningSummary"
          }
        },
        "additionalProperties": false,
        "description": "The full bulk-screening response: per-row results plus a summary."
      },
      "BulkScreeningRowResult": {
        "type": "object",
        "properties": {
          "rowIndex": {
            "type": "integer",
            "format": "int32"
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "userReference": {
            "type": "string",
            "nullable": true
          },
          "screeningId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "isMatch": {
            "type": "boolean"
          },
          "decision": {
            "type": "string",
            "nullable": true
          },
          "riskScore": {
            "type": "integer",
            "format": "int32"
          },
          "matchCount": {
            "type": "integer",
            "format": "int32"
          },
          "error": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The result of screening a single bulk row. AMLService.Application.Bulk.BulkScreeningRowResult.Error is set (and the\r\n            screening fields left at their defaults) when that row failed in isolation."
      },
      "BulkScreeningSubject": {
        "type": "object",
        "properties": {
          "userReference": {
            "type": "string",
            "description": "Caller's own correlation reference (e.g. their customer id).",
            "nullable": true
          },
          "fullName": {
            "type": "string",
            "description": "Full name of the person to screen. Required.",
            "nullable": true
          },
          "dateOfBirth": {
            "type": "string",
            "description": "Date of birth, ISO yyyy-MM-dd (or yyyy). Optional.",
            "nullable": true
          },
          "nationality": {
            "type": "string",
            "description": "Nationality as an ISO country code. Optional.",
            "nullable": true
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Known aliases / alternate spellings.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One subject to screen in a bulk request (JSON array element). The tenant is taken from the\r\nauthenticated principal, never from here. Aliases are an explicit list (the CSV path splits\r\nthe semicolon-separated alias column into this)."
      },
      "BulkScreeningSummary": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "format": "int32"
          },
          "screened": {
            "type": "integer",
            "format": "int32"
          },
          "failed": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Aggregate counts for a bulk run."
      },
      "CaseAttachmentResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "fileName": {
            "type": "string",
            "nullable": true
          },
          "contentType": {
            "type": "string",
            "nullable": true
          },
          "sizeBytes": {
            "type": "integer",
            "format": "int64"
          },
          "uploadedBy": {
            "type": "string",
            "nullable": true
          },
          "uploadedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "Attachment metadata (no bytes) returned by the list/upload endpoints."
      },
      "CaseDetailResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "dateOfBirth": {
            "type": "string",
            "nullable": true
          },
          "nationality": {
            "type": "string",
            "nullable": true
          },
          "userReference": {
            "type": "string",
            "nullable": true
          },
          "isMatch": {
            "type": "boolean"
          },
          "aggregateScore": {
            "type": "number",
            "format": "double"
          },
          "classification": {
            "type": "string",
            "nullable": true
          },
          "decision": {
            "type": "string",
            "nullable": true
          },
          "riskScore": {
            "type": "integer",
            "format": "int32"
          },
          "riskBand": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "reviewStatus": {
            "type": "string",
            "nullable": true
          },
          "reviewedBy": {
            "type": "string",
            "nullable": true
          },
          "reviewedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "reviewReason": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "matches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseMatchedEntity"
            },
            "nullable": true
          },
          "notes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseNoteResponse"
            },
            "nullable": true
          },
          "factors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RiskFactorResponse"
            },
            "nullable": true
          },
          "monitoredSubjectId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "reason": {
            "$ref": "#/components/schemas/DecisionReasonResponse"
          },
          "correlationId": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Full case detail: the screening verdict, matches, disposition and note thread."
      },
      "CaseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "cryptoId": {
            "type": "string",
            "nullable": true
          },
          "address": {
            "$ref": "#/components/schemas/AddressDto"
          },
          "identification": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IdentificationDto"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CaseListResponse": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseSummary"
            },
            "nullable": true
          },
          "total": {
            "type": "integer",
            "format": "int32"
          },
          "skip": {
            "type": "integer",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "A page of cases plus the total count for the filter."
      },
      "CaseMatchedEntity": {
        "type": "object",
        "properties": {
          "sourceList": {
            "type": "string",
            "nullable": true
          },
          "externalId": {
            "type": "string",
            "nullable": true
          },
          "matchedName": {
            "type": "string",
            "nullable": true
          },
          "score": {
            "type": "number",
            "format": "double"
          },
          "classification": {
            "type": "string",
            "nullable": true
          },
          "rejectionTag": {
            "type": "string",
            "nullable": true
          },
          "pepTier": {
            "type": "string",
            "nullable": true
          },
          "pepJurisdiction": {
            "type": "string",
            "nullable": true
          },
          "dataAsOf": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "leadershipSummary": {
            "type": "string",
            "nullable": true
          },
          "leadershipSourceUrl": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CaseNoteResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "author": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "isSystem": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "CaseSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "isMatch": {
            "type": "boolean"
          },
          "decision": {
            "type": "string",
            "nullable": true
          },
          "riskScore": {
            "type": "integer",
            "format": "int32"
          },
          "riskBand": {
            "type": "string",
            "nullable": true
          },
          "reviewStatus": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "userReference": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One row in the case list."
      },
      "ConsentHistoryResponse": {
        "type": "object",
        "properties": {
          "subjectReference": {
            "type": "string",
            "nullable": true
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConsentResponse"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ConsentResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "subjectReference": {
            "type": "string",
            "nullable": true
          },
          "consentVersion": {
            "type": "string",
            "nullable": true
          },
          "consentText": {
            "type": "string",
            "nullable": true
          },
          "consentTextSha256": {
            "type": "string",
            "nullable": true
          },
          "channel": {
            "type": "string",
            "nullable": true
          },
          "capturedAt": {
            "type": "string",
            "format": "date-time"
          },
          "withdrawn": {
            "type": "boolean"
          },
          "withdrawnAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CountByLabel": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string",
            "nullable": true
          },
          "count": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "A label paired with its count (e.g. a decision or risk band and how many screenings had it)."
      },
      "CountryCoverage": {
        "type": "object",
        "properties": {
          "countryIso": {
            "type": "string",
            "nullable": true
          },
          "countryQid": {
            "type": "string",
            "nullable": true
          },
          "rollup": {
            "type": "string",
            "nullable": true
          },
          "cells": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CountryCoverageCell"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One country's row: its office cells + the rolled-up status."
      },
      "CountryCoverageCell": {
        "type": "object",
        "properties": {
          "office": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "expectedCardinality": {
            "type": "integer",
            "format": "int32"
          },
          "ingestedHolders": {
            "type": "integer",
            "format": "int32"
          },
          "knownGap": {
            "type": "boolean"
          }
        },
        "additionalProperties": false,
        "description": "One (country × office) cell of the published grid."
      },
      "CountryCoverageResponse": {
        "type": "object",
        "properties": {
          "generatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "registryVersion": {
            "type": "string",
            "nullable": true
          },
          "countries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CountryCoverage"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The published per-country coverage grid — the visible \"are we complete?\" answer, stamped with\r\n            the registry version it was measured against (the versioned denominator, ERIC-1).\r\n            AMLService.Application.Coverage.CountryCoverageResponse.GeneratedAt is null when no audit has ever run: the grid below is the\r\n            declared registry structure only, not a measurement — never stamp a request-time timestamp on it, or a\r\n            never-computed grid becomes indistinguishable from a genuinely-measured all-red one (ERIC-1)."
      },
      "CoverageMatrixResponse": {
        "type": "object",
        "properties": {
          "generatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "hasGaps": {
            "type": "boolean"
          },
          "totalReachableButMissed": {
            "type": "integer",
            "format": "int32"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CoverageRowResponse"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The published coverage matrix: the self-audit result shaped for the API + UI + docs.\r\n            AMLService.Application.Coverage.CoverageMatrixResponse.GeneratedAt is null when no audit has ever run: the rows below are the\r\n            declared manifest structure only, not a measurement — never stamp a request-time timestamp on the\r\n            structure-only pre-warm grid, or a never-computed matrix becomes indistinguishable from a genuinely\r\n            measured all-zero one (ERIC-1, mirrors the country grid's `CountryCoverageResponse.GeneratedAt`)."
      },
      "CoveragePresetDto": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "enabledLists": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "pepTiers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A ready-made coverage preset as surfaced to the console (for the preset picker)."
      },
      "CoverageRowResponse": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "fatfLabel": {
            "type": "string",
            "nullable": true
          },
          "tier": {
            "type": "string",
            "nullable": true
          },
          "availableCurrentHolders": {
            "type": "integer",
            "format": "int32"
          },
          "ingestedHolders": {
            "type": "integer",
            "format": "int32"
          },
          "hasData": {
            "type": "boolean"
          },
          "coveragePct": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "reachableButMissed": {
            "type": "integer",
            "format": "int32"
          },
          "hasGap": {
            "type": "boolean"
          }
        },
        "additionalProperties": false,
        "description": "One category row of the published matrix. AMLService.Application.Coverage.CoverageRowResponse.HasData tells a consumer whether\r\n            AMLService.Application.Coverage.CoverageRowResponse.CoveragePct is a real measurement: when it is `false`, the category was not measured\r\n            (a topic-driven row, or a not-yet-ingested one) and clients/docs must render \"not measured / no data\"\r\n            rather than a number — AMLService.Application.Coverage.CoverageRowResponse.CoveragePct is `null` in that case, so it can never be\r\n            misread as 100% or 0%."
      },
      "CreateWebhookRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "nullable": true
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Register a webhook endpoint. Events defaults to `screening.completed` when omitted."
      },
      "CreatedWebhookCaptureBinDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The bin's stable id.",
            "format": "uuid"
          },
          "token": {
            "type": "string",
            "description": "The plaintext capture token. Shown once; unrecoverable afterwards.",
            "nullable": true
          },
          "path": {
            "type": "string",
            "description": "The relative path to POST at (`/v1/webhooks/receiver/{token}`). Relative, because the public\r\norigin depends on how the service is fronted; the portal joins it to its configured API base.",
            "nullable": true
          },
          "tokenPrefix": {
            "type": "string",
            "description": "Non-secret prefix retained for display after the plaintext is gone.",
            "nullable": true
          },
          "expiresAfterHours": {
            "type": "integer",
            "description": "How long any capture in this bin is kept before it is purged.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "A freshly created (or rotated) capture bin. Token is returned ONCE — we store\r\nonly its hash, exactly like a webhook signing secret or an API key."
      },
      "CreatedWebhookDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "nullable": true
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "signingSecret": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A freshly created webhook endpoint. The signing secret is returned ONCE."
      },
      "DeathDateMethodConfig": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          }
        },
        "additionalProperties": false,
        "description": "Method 1 (`death_date`, recorded): on/off. No threshold — a recorded death is a fact."
      },
      "DeceasedConfigResponse": {
        "type": "object",
        "properties": {
          "hideDeceased": {
            "type": "boolean"
          },
          "deathDate": {
            "$ref": "#/components/schemas/DeathDateMethodConfig"
          },
          "ageOverMax": {
            "$ref": "#/components/schemas/AgeOverMaxMethodConfig"
          },
          "serviceOverMax": {
            "$ref": "#/components/schemas/ServiceOverMaxMethodConfig"
          }
        },
        "additionalProperties": false,
        "description": "The per-tenant deceased-determination configuration (COV-8 + COV-12), as it appears on the\r\n`GET/PUT /v1/tenants/me/deceased-config` endpoints AND echoed on a screening response as\r\n`tenantDeceasedConfig` — the data the screening page renders the \"active determination methods +\r\nthresholds\" step from. AMLService.Application.Screening.DeceasedConfigResponse.HideDeceased is the COV-8 hide switch; the three nested blocks\r\nare the COV-12 determination methods."
      },
      "DeceasedMethodResponse": {
        "type": "object",
        "properties": {
          "method": {
            "type": "string",
            "nullable": true
          },
          "basis": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One deceased-determination method that fired on a match, with its arithmetic basis."
      },
      "DecisionMatrixCellDto": {
        "type": "object",
        "properties": {
          "category": {
            "type": "string",
            "description": "Canonical category token: `sanctions` / `criminal` / `pep` / `adverse_media`.",
            "nullable": true
          },
          "tier": {
            "type": "string",
            "description": "Evidence tier token: `exact_name_exact_dob` / `exact_name_no_dob` / `weak_or_partial_name`.",
            "nullable": true
          },
          "multiplicity": {
            "type": "string",
            "description": "Multiplicity token: `single` / `multiple`.",
            "nullable": true
          },
          "decision": {
            "type": "string",
            "description": "The decision token: `Pass` / `Review` / `Fail`.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One cell of the decision matrix as carried over the API: a (category × evidence-tier × multiplicity)\r\ncoordinate and the AMLService.Application.Risk.DecisionMatrixCellDto.Decision it maps to. All fields are the stable string tokens\r\n(`DecisionMatrixTokens` / `RiskCategories` / `Decision` names)."
      },
      "DecisionMatrixGridDto": {
        "type": "object",
        "properties": {
          "cells": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DecisionMatrixCellDto"
            },
            "description": "Every (category × tier × multiplicity) cell, in a stable order.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A whole matrix (all 24 resolvable cells) as an ordered list of cells."
      },
      "DecisionMatrixViewDto": {
        "type": "object",
        "properties": {
          "tenantId": {
            "type": "string",
            "description": "The tenant this matrix belongs to.",
            "format": "uuid"
          },
          "unconfirmedPosture": {
            "type": "string",
            "description": "The tenant's unconfirmed-hit posture (`Review` / `Fail`) that seeds its default cells.",
            "nullable": true
          },
          "effective": {
            "$ref": "#/components/schemas/DecisionMatrixGridDto"
          },
          "systemDefault": {
            "$ref": "#/components/schemas/DecisionMatrixGridDto"
          },
          "ruledOutNote": {
            "type": "string",
            "description": "A human-readable note documenting the \"different name → Pass (ruled out upstream)\" case that is not an editable cell. (Exact name + mismatched DOB is now a real editable cell, DM-3, not ruled out.)",
            "nullable": true
          },
          "dobMismatchSurfacing": {
            "type": "string",
            "description": "🟡 PROVISIONAL (#368). The tenant's DoB-mismatch surfacing mode as a readable\r\n            string — `\"StrictExactName\"` or `\"HighScore\"` — read from the tenant's profile. Admin-readable here\r\n            (governed exactly like the matrix: master edits, tenant admins read); the master sets it via the PUT.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The read-only view of a tenant's decision matrix (admin transparency page): the tenant's EFFECTIVE\r\nmatrix (posture-seeded default + this tenant's overrides, normalized) alongside the system DEFAULT\r\nmatrix (the shipped baseline at the standard Review posture) so the two can be shown side by side."
      },
      "DecisionMatrixWriteDto": {
        "type": "object",
        "properties": {
          "cells": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DecisionMatrixCellDto"
            },
            "description": "The cell overrides to apply.",
            "nullable": true
          },
          "dobMismatchSurfacing": {
            "type": "string",
            "description": "🟡 PROVISIONAL (#368). Optional. The tenant's DoB-mismatch surfacing mode as a\r\n            readable string — `\"StrictExactName\"` or `\"HighScore\"`, case-insensitive. Absent/blank leaves the\r\n            current mode unchanged; a non-empty value that is not a defined mode (or a raw ordinal like `\"1\"`) is a 400.\r\n            Master-only (this whole PUT is `Platform.Operations`).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The MASTER (platform-operator) write payload: the tenant's decision-matrix cell overrides. PUT\r\nsemantics — the provided cells REPLACE the tenant's entire override set. An empty list resets the\r\ntenant to the posture-seeded default. Watchlist→Pass and softened-multiplicity cells are normalized\r\naway (a watchlist cell floors at Review; a Multiple cell floors at its Single sibling), so the stored\r\n/ returned effective matrix always honours the governing invariants."
      },
      "DecisionReasonResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "The stable SCREAMING_SNAKE reason token (e.g. `SANCTIONS_EXACT_NAME_DOB`).",
            "nullable": true
          },
          "summary": {
            "type": "string",
            "description": "A one-line English explanation for an analyst.",
            "nullable": true
          },
          "category": {
            "type": "string",
            "description": "The driving category (`sanctions` / `pep` / `adverse_media` /\r\n            `criminal`); omitted on a Pass.",
            "nullable": true
          },
          "evidence": {
            "type": "string",
            "description": "The evidence tier (`exact_name_exact_dob` …); omitted on a Pass.",
            "nullable": true
          },
          "rule": {
            "type": "string",
            "description": "The matrix rule that fired (e.g. `\"Sanctions · Exact+DOB → Fail\"`); omitted when\r\n            none applies.",
            "nullable": true
          },
          "pepClass": {
            "type": "string",
            "description": "The PEP class (e.g. `\"1_national\"`); present only for a PEP reason.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The `reason` object on a AMLService.Application.Screening.ScreeningResponse (DM-6 / #235): a machine-readable\r\nexplanation of the Pass / Review / Fail decision. Present only when the request set\r\n`includeReasoning`. The wire shape of a AMLService.Domain.Risk.DecisionReason; the optional facets are\r\nomitted (not serialized as `null`) so a Pass reason is just `code` + `summary`, matching\r\nthe approved mockup. Purely descriptive — surfacing it never changes the decision."
      },
      "DemoConfigResponse": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "Whether a public demo key is configured. False = the zero-setup demo is unavailable and the\r\ncalling page should degrade gracefully (hide/disable its \"try a sample\" affordance) rather than\r\nfire a doomed request."
          },
          "publicApiKey": {
            "type": "string",
            "description": "The shared public demo API key, or empty when Enabled is false.\r\n            \r\nThis value is PUBLIC BY CONSTRUCTION — it is handed to an anonymous browser, so anyone can lift it\r\nfrom devtools. That is the accepted trade for a zero-setup public demo, and it is why the demo\r\ntenant is quota- and rate-limited (monthly quota, per-minute burst cap, per-IP hourly cap, and a\r\nbatch row cap) and is treated as disposable/rotatable. It must NEVER be a real customer's key.\r\n            \r\nServing it from configuration rather than hard-coding it in the served JS is the point: the key can\r\nbe rotated by changing one env var, with no code change, no redeploy of the frontend, and no\r\ncredential in a tracked file.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The public demo tenant's browser-facing configuration. Served anonymously so the playground (and\r\nthe public docs pages) can screen with zero setup."
      },
      "DobMismatchSurfacing": {
        "enum": [
          0,
          1
        ],
        "type": "integer",
        "description": "Per-tenant strategy for whether a name hit whose date-of-birth DIFFERS beyond tolerance is\r\nSURFACED for human review or silently discarded as a false positive.",
        "format": "int32"
      },
      "EraseSubjectResponse": {
        "type": "object",
        "properties": {
          "subjectReference": {
            "type": "string",
            "nullable": true
          },
          "recordsAnonymized": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "ExportAuditEntry": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "actor": {
            "type": "string",
            "nullable": true
          },
          "action": {
            "type": "string",
            "nullable": true
          },
          "targetType": {
            "type": "string",
            "nullable": true
          },
          "targetId": {
            "type": "string",
            "nullable": true
          },
          "metadata": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "ExportCase": {
        "type": "object",
        "properties": {
          "screeningId": {
            "type": "string",
            "format": "uuid"
          },
          "reviewStatus": {
            "type": "string",
            "nullable": true
          },
          "reviewedBy": {
            "type": "string",
            "nullable": true
          },
          "reviewedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "reviewReason": {
            "type": "string",
            "nullable": true
          },
          "notes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExportNote"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ExportConsent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "consentVersion": {
            "type": "string",
            "nullable": true
          },
          "consentText": {
            "type": "string",
            "nullable": true
          },
          "consentTextSha256": {
            "type": "string",
            "nullable": true
          },
          "channel": {
            "type": "string",
            "nullable": true
          },
          "capturedAt": {
            "type": "string",
            "format": "date-time"
          },
          "withdrawn": {
            "type": "boolean"
          },
          "withdrawnAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ExportFlags": {
        "type": "object",
        "properties": {
          "restricted": {
            "type": "boolean"
          },
          "objected": {
            "type": "boolean"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "ExportMatch": {
        "type": "object",
        "properties": {
          "sourceList": {
            "type": "string",
            "nullable": true
          },
          "externalId": {
            "type": "string",
            "nullable": true
          },
          "matchedName": {
            "type": "string",
            "nullable": true
          },
          "score": {
            "type": "number",
            "format": "double"
          },
          "classification": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ExportMonitoring": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "active": {
            "type": "boolean"
          },
          "lastDecision": {
            "type": "string",
            "nullable": true
          },
          "lastScreenedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "ExportNote": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "author": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "isSystem": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "ExportRequest": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "requestedBy": {
            "type": "string",
            "nullable": true
          },
          "requestedAt": {
            "type": "string",
            "format": "date-time"
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ExportScreening": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "dateOfBirth": {
            "type": "string",
            "nullable": true
          },
          "nationality": {
            "type": "string",
            "nullable": true
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "isMatch": {
            "type": "boolean"
          },
          "aggregateScore": {
            "type": "number",
            "format": "double"
          },
          "classification": {
            "type": "string",
            "nullable": true
          },
          "decision": {
            "type": "string",
            "nullable": true
          },
          "riskScore": {
            "type": "integer",
            "format": "int32"
          },
          "riskBand": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "matchedEntities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExportMatch"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ExportSubject": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "dateOfBirth": {
            "type": "string",
            "nullable": true
          },
          "nationality": {
            "type": "string",
            "nullable": true
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastScreenedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Identity a tenant registered about this person via `POST /v1/subjects`. Included in the SAR\r\nbundle because it is personal data we hold BEFORE any screening obligation arises — a subject\r\nregistered and never screened would otherwise be invisible to the person it describes."
      },
      "ExternalProviderResponse": {
        "required": [
          "createdAt",
          "enabled",
          "hasApiKey",
          "includeDatasets",
          "keywords",
          "providerType",
          "topics",
          "updatedAt"
        ],
        "type": "object",
        "properties": {
          "providerType": {
            "type": "string",
            "nullable": true
          },
          "enabled": {
            "type": "boolean"
          },
          "hasApiKey": {
            "type": "boolean"
          },
          "collection": {
            "type": "string",
            "nullable": true
          },
          "algorithm": {
            "type": "string",
            "nullable": true
          },
          "threshold": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "includeDatasets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "topics": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "baseUrl": {
            "type": "string",
            "nullable": true
          },
          "keywords": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "maxRecords": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "A tenant's external-provider config as returned to an admin. The API key is NEVER returned —\r\nonly AMLService.Application.Screening.ExternalProviderResponse.HasApiKey indicates whether one is stored."
      },
      "Identification": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "idNumber": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "IdentificationDto": {
        "type": "object",
        "properties": {
          "idNumber": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "IngestJobStatus": {
        "type": "object",
        "properties": {
          "running": {
            "type": "boolean",
            "description": "Whether a run is queued or running on ANY pod."
          },
          "source": {
            "type": "string",
            "description": "The source being refreshed, or \"all configured sources\" for a scheduled sweep.",
            "nullable": true
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "elapsedSeconds": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "lastCompletedAt": {
            "type": "string",
            "description": "When the most recent run of ANY outcome finished. Answers \"when did a run\r\n            last END\", which is NOT the same as \"when did the data last refresh successfully\": a long explicit run\r\n            holding the single-flight slot, or a source (e.g. EU) failing every scheduled cycle, moves this forward\r\n            while the corpus stays as stale as its last GOOD refresh.",
            "format": "date-time",
            "nullable": true
          },
          "lastSuccess": {
            "type": "boolean",
            "description": "Whether the run behind AMLService.Application.Ingest.IngestJobStatus.LastCompletedAt succeeded.",
            "nullable": true
          },
          "lastError": {
            "type": "string",
            "nullable": true
          },
          "lastSuccessAt": {
            "type": "string",
            "description": "When the most recent SUCCEEDED run finished — the true data-freshness\r\n            marker. Distinct from AMLService.Application.Ingest.IngestJobStatus.LastCompletedAt: it does not move on a failed/partial run, so\r\n            monitoring can tell \"a run just finished\" from \"the data is actually fresh\". Null until a run has\r\n            succeeded. (Per-source last-refresh is served separately by the watchlist source-health endpoint.)",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Live status of the ingest job: whether one is running anywhere in the deployment, and the last\r\noutcome. Projected from the `JobRuns` table by\r\nM:AMLService.Application.Jobs.JobTriggerService.IngestStatusAsync(System.Threading.CancellationToken) — the shape is unchanged from when it was a\r\nsnapshot of per-process fields, so existing clients read it identically; only its truthfulness across\r\nreplicas changed."
      },
      "IngestRunResponse": {
        "type": "object",
        "properties": {
          "sourceList": {
            "type": "string",
            "nullable": true
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          },
          "finishedAt": {
            "type": "string",
            "format": "date-time"
          },
          "durationSeconds": {
            "type": "number",
            "format": "double"
          },
          "success": {
            "type": "boolean"
          },
          "entityCount": {
            "type": "integer",
            "format": "int32"
          },
          "version": {
            "type": "string",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One historical watchlist-refresh run, for the data-freshness / provenance timeline."
      },
      "IssuedApiKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "apiKey": {
            "type": "string",
            "nullable": true
          },
          "prefix": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Issued API key (plaintext shown once + its non-secret prefix and id)."
      },
      "JobAlreadyRunningDto": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "nullable": true
          },
          "runId": {
            "type": "string",
            "format": "uuid"
          },
          "jobName": {
            "type": "string",
            "nullable": true
          },
          "triggerSource": {
            "type": "string",
            "nullable": true
          },
          "triggeredBy": {
            "type": "string",
            "nullable": true
          },
          "triggeredAt": {
            "type": "string",
            "format": "date-time"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The 409 body when a trigger arrives while the job is already going. Carries the occupying run's id\r\nand start time so the console can say \"already running since HH:MM\" instead of showing a bare error —\r\nthe whole reason this is an explicit response rather than a silent no-op or a queued duplicate."
      },
      "JobRunDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "jobName": {
            "type": "string",
            "nullable": true
          },
          "triggerSource": {
            "type": "string",
            "nullable": true
          },
          "triggeredBy": {
            "type": "string",
            "nullable": true
          },
          "triggeredAt": {
            "type": "string",
            "format": "date-time"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "outcome": {
            "type": "string",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "leaseOwner": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One run of a job, with full provenance. `TriggeredAt` and `StartedAt` are separate\r\n            on purpose: a queued run may wait for a worker, and conflating them would hide that wait."
      },
      "JobRunState": {
        "enum": [
          0,
          1,
          2,
          3
        ],
        "type": "integer",
        "description": "The coarse lifecycle state of a background job in the unified job-status feed.",
        "format": "int32"
      },
      "JobSnapshot": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "state": {
            "$ref": "#/components/schemas/JobRunState"
          },
          "phase": {
            "type": "string",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "processed": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "total": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "runningTotalEntities": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "success": {
            "type": "boolean",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "An immutable point-in-time view of one background job for the unified `/v1/jobs` feed:\r\nits coarse AMLService.Application.Jobs.JobSnapshot.State, the current AMLService.Application.Jobs.JobSnapshot.Phase, a progress measure\r\n(AMLService.Application.Jobs.JobSnapshot.Processed of AMLService.Application.Jobs.JobSnapshot.Total), the running entity total, and the run timestamps\r\nplus the last outcome. Everything past the state is optional — a job that reports no progress\r\nmeasure simply leaves those null and the UI shows an indeterminate bar."
      },
      "LeaderRowDto": {
        "type": "object",
        "properties": {
          "person": {
            "type": "string",
            "nullable": true
          },
          "qid": {
            "type": "string",
            "nullable": true
          },
          "dob": {
            "type": "string",
            "nullable": true
          },
          "personUrl": {
            "type": "string",
            "nullable": true
          },
          "countryIso": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          },
          "countryQid": {
            "type": "string",
            "nullable": true
          },
          "office": {
            "type": "string",
            "nullable": true
          },
          "officeQid": {
            "type": "string",
            "nullable": true
          },
          "officeUrl": {
            "type": "string",
            "nullable": true
          },
          "role": {
            "type": "string",
            "nullable": true
          },
          "termStart": {
            "type": "string",
            "nullable": true
          },
          "termEnd": {
            "type": "string",
            "nullable": true
          },
          "isCurrent": {
            "type": "boolean"
          },
          "pepClass": {
            "type": "string",
            "nullable": true
          },
          "pepClassLabel": {
            "type": "string",
            "nullable": true
          },
          "relativeOf": {
            "$ref": "#/components/schemas/RelativeOfDto"
          }
        },
        "additionalProperties": false,
        "description": "One transparent catalog row: a leadership term (person × office × term) or, when relatives are\r\nrequested, a leader's relative. Every field a portal user or auditor needs to see exactly what we\r\nhold — the person + their Wikidata source, the country + office + office source, the term dates,\r\nwhether it is current, and the derived AMLService.Application.Leaders.LeaderRowDto.PepClass (see the customer-relative caveat on\r\nAMLService.Domain.Screening.LeaderPepClassifier). Relative rows carry AMLService.Application.Leaders.LeaderRowDto.RelativeOf\r\nand leave the office/term fields null."
      },
      "LeadersPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LeaderRowDto"
            },
            "nullable": true
          },
          "total": {
            "type": "integer",
            "format": "int32"
          },
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "A page of the leaders catalog. AMLService.Application.Leaders.LeadersPage.Total counts the leadership TERM rows matching the\r\nfilters (before paging); relatives, when requested, are appended to AMLService.Application.Leaders.LeadersPage.Items for the\r\nleaders on this page and are not counted in AMLService.Application.Leaders.LeadersPage.Total."
      },
      "ListVersionResponse": {
        "type": "object",
        "properties": {
          "version": {
            "type": "string",
            "description": "Version string of the ingested list.",
            "nullable": true
          },
          "publishedAt": {
            "type": "string",
            "description": "When the source published this version, if known.",
            "format": "date-time",
            "nullable": true
          },
          "downloadedAt": {
            "type": "string",
            "description": "When this service last ingested it.",
            "format": "date-time"
          },
          "entityCount": {
            "type": "integer",
            "description": "Number of entities ingested for this version.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Version metadata for one ingested source list, surfaced by `GET /v1/lists/version`."
      },
      "MatchDeceasedResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "`\"recorded\"` (a source death date) or `\"presumed\"` (an inference).",
            "nullable": true
          },
          "methods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeceasedMethodResponse"
            },
            "description": "Every determination method that fired, with its basis.",
            "nullable": true
          },
          "hiddenByConfig": {
            "type": "boolean",
            "description": "TRUE when this match was suppressed (hidden) by the deceased-hide policy —\r\n            i.e. it appears under `suppressedMatches`, not the default list."
          }
        },
        "additionalProperties": false,
        "description": "The deceased determination surfaced on a single match (COV-12): its honesty grade, the method(s) that\r\nfired with their arithmetic basis, and whether the tenant's hide policy hid it. Null on a match that\r\nwas not determined deceased."
      },
      "MatchQuery": {
        "type": "object",
        "properties": {
          "schema": {
            "type": "string",
            "description": "Entity schema: Person, Company, Organization, etc.\r\nDefault is Person.",
            "nullable": true
          },
          "properties": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Entity attributes mapped to lists of values, e.g.\r\n{ \"name\": [\"John Doe\"], \"birthDate\": [\"1975-04-21\"], \"nationality\": [\"us\"] }",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Individual entity example to match against OpenSanctions."
      },
      "MatchResponseItem": {
        "type": "object",
        "properties": {
          "query": {
            "$ref": "#/components/schemas/MatchQuery"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MatchResult"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MatchResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "schema": {
            "type": "string",
            "nullable": true
          },
          "score": {
            "type": "number",
            "format": "double"
          },
          "caption": {
            "type": "string",
            "description": "Best display name chosen by the provider (when present at top level).",
            "nullable": true
          },
          "datasets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Dataset slugs this entity appears in (e.g. \"us_ofac_sdn\", \"eu_fsf\").",
            "nullable": true
          },
          "properties": {
            "type": "object",
            "additionalProperties": {
              "nullable": true
            },
            "nullable": true
          },
          "programId": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MatchedEntityResponse": {
        "type": "object",
        "properties": {
          "sourceList": {
            "type": "string",
            "nullable": true
          },
          "externalId": {
            "type": "string",
            "nullable": true
          },
          "matchedName": {
            "type": "string",
            "nullable": true
          },
          "score": {
            "type": "number",
            "format": "double"
          },
          "classification": {
            "type": "string",
            "nullable": true
          },
          "rejectionTag": {
            "type": "string",
            "nullable": true
          },
          "dobCorroborated": {
            "type": "boolean"
          },
          "discardReason": {
            "type": "string",
            "nullable": true
          },
          "pepTier": {
            "type": "string",
            "description": "PEP tier for a pep match (slide 16), null otherwise.",
            "nullable": true
          },
          "adverseMediaCategory": {
            "type": "string",
            "description": "Adverse-media category for an adverse_media match (slide 21), null otherwise.",
            "nullable": true
          },
          "criminalCategory": {
            "type": "string",
            "description": "Criminal sub-category for a criminal match (Terrorism / General), null otherwise.",
            "nullable": true
          },
          "pepJurisdiction": {
            "type": "string",
            "description": "ISO alpha-2 of the office jurisdiction that drove the PEP tier (the\r\n            \"why\" behind Domestic/Foreign), null when none.",
            "nullable": true
          },
          "dataAsOf": {
            "type": "string",
            "description": "When this match's underlying data was last confirmed present in its source,\r\n            for recency transparency; null when unknown.",
            "format": "date-time",
            "nullable": true
          },
          "leadershipSummary": {
            "type": "string",
            "description": "Country-anchored leadership summary (office + country + term\r\n            period), e.g. \"Head of state of United States · 2025-01-20 – present\"; null when none.",
            "nullable": true
          },
          "leadershipSourceUrl": {
            "type": "string",
            "description": "The office's Wikidata source URL backing the leadership summary\r\n            (per-result provenance); null when none.",
            "nullable": true
          },
          "headline": {
            "type": "string",
            "nullable": true
          },
          "publisher": {
            "type": "string",
            "nullable": true
          },
          "publishedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "matchedPerson": {
            "type": "string",
            "nullable": true
          },
          "exculpatoryOutcome": {
            "type": "string",
            "nullable": true
          },
          "articleTone": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "isObservation": {
            "type": "boolean"
          },
          "postScreeningFindings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PostScreeningFindingResponse"
            },
            "nullable": true
          },
          "deceased": {
            "$ref": "#/components/schemas/MatchDeceasedResponse"
          }
        },
        "additionalProperties": false,
        "description": "A single matched entity in a AMLService.Application.Screening.ScreeningResponse."
      },
      "MatchingPresetDto": {
        "required": [
          "candidateLimit",
          "defaultFuzzyThreshold",
          "displayName",
          "dobMismatchPenalty",
          "dobYearTolerance",
          "exactMatch",
          "isDefault",
          "key",
          "nicknamesEnabled",
          "phoneticEnabled",
          "resultCap",
          "summary",
          "trigramFloor"
        ],
        "type": "object",
        "properties": {
          "defaultFuzzyThreshold": {
            "type": "number",
            "format": "double"
          },
          "phoneticEnabled": {
            "type": "boolean"
          },
          "exactMatch": {
            "type": "boolean"
          },
          "nicknamesEnabled": {
            "type": "boolean"
          },
          "trigramFloor": {
            "type": "number",
            "format": "double"
          },
          "candidateLimit": {
            "type": "integer",
            "format": "int32"
          },
          "resultCap": {
            "type": "integer",
            "format": "int32"
          },
          "dobYearTolerance": {
            "type": "integer",
            "format": "int32"
          },
          "dobMismatchPenalty": {
            "type": "number",
            "format": "double"
          },
          "dobMismatchSurfacing": {
            "type": "string",
            "description": "🟡 PROVISIONAL (#368). Strategy for surfacing a name hit whose DoB differs beyond\r\n            tolerance, on the wire as a readable string — `\"StrictExactName\"` (default) or\r\n            `\"HighScore\"`, case-insensitive (mirrors `SanctionsUnconfirmedDecision`; a raw enum\r\n            ordinal like `\"1\"` is rejected). NOT `required` (unlike the other knobs): the feature is\r\n            provisional and its safe default is StrictExactName, so an existing client that omits it keeps the\r\n            historical behaviour rather than getting a 400. See AMLService.Domain.Screening.DobMismatchSurfacing.",
            "nullable": true
          },
          "dobMismatchHighScoreThreshold": {
            "type": "number",
            "description": "🟡 PROVISIONAL (#368). Under HighScore surfacing, the provider score (0-1) a partial-name\r\n            DoB-mismatch must reach to surface for review. Non-required; defaults to 0.97 (the near-exact bar).",
            "format": "double"
          },
          "enabledLists": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Watchlists to screen against; empty = all lists.",
            "nullable": true
          },
          "key": {
            "type": "string",
            "nullable": true
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "isDefault": {
            "type": "boolean"
          }
        },
        "additionalProperties": false,
        "description": "One of the three system presets, with its parameter values for the UI to preview / apply."
      },
      "MatchingProfileDto": {
        "required": [
          "candidateLimit",
          "createdAt",
          "defaultFuzzyThreshold",
          "dobMismatchPenalty",
          "dobYearTolerance",
          "exactMatch",
          "id",
          "isActive",
          "name",
          "nicknamesEnabled",
          "phoneticEnabled",
          "resultCap",
          "trigramFloor",
          "updatedAt"
        ],
        "type": "object",
        "properties": {
          "defaultFuzzyThreshold": {
            "type": "number",
            "format": "double"
          },
          "phoneticEnabled": {
            "type": "boolean"
          },
          "exactMatch": {
            "type": "boolean"
          },
          "nicknamesEnabled": {
            "type": "boolean"
          },
          "trigramFloor": {
            "type": "number",
            "format": "double"
          },
          "candidateLimit": {
            "type": "integer",
            "format": "int32"
          },
          "resultCap": {
            "type": "integer",
            "format": "int32"
          },
          "dobYearTolerance": {
            "type": "integer",
            "format": "int32"
          },
          "dobMismatchPenalty": {
            "type": "number",
            "format": "double"
          },
          "dobMismatchSurfacing": {
            "type": "string",
            "description": "🟡 PROVISIONAL (#368). Strategy for surfacing a name hit whose DoB differs beyond\r\n            tolerance, on the wire as a readable string — `\"StrictExactName\"` (default) or\r\n            `\"HighScore\"`, case-insensitive (mirrors `SanctionsUnconfirmedDecision`; a raw enum\r\n            ordinal like `\"1\"` is rejected). NOT `required` (unlike the other knobs): the feature is\r\n            provisional and its safe default is StrictExactName, so an existing client that omits it keeps the\r\n            historical behaviour rather than getting a 400. See AMLService.Domain.Screening.DobMismatchSurfacing.",
            "nullable": true
          },
          "dobMismatchHighScoreThreshold": {
            "type": "number",
            "description": "🟡 PROVISIONAL (#368). Under HighScore surfacing, the provider score (0-1) a partial-name\r\n            DoB-mismatch must reach to surface for review. Non-required; defaults to 0.97 (the near-exact bar).",
            "format": "double"
          },
          "enabledLists": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Watchlists to screen against; empty = all lists.",
            "nullable": true
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "isActive": {
            "type": "boolean"
          },
          "basePresetKey": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "A saved named matching profile as returned to an admin."
      },
      "MatchingProfileInput": {
        "required": [
          "candidateLimit",
          "defaultFuzzyThreshold",
          "dobMismatchPenalty",
          "dobYearTolerance",
          "exactMatch",
          "nicknamesEnabled",
          "phoneticEnabled",
          "resultCap",
          "trigramFloor"
        ],
        "type": "object",
        "properties": {
          "defaultFuzzyThreshold": {
            "type": "number",
            "format": "double"
          },
          "phoneticEnabled": {
            "type": "boolean"
          },
          "exactMatch": {
            "type": "boolean"
          },
          "nicknamesEnabled": {
            "type": "boolean"
          },
          "trigramFloor": {
            "type": "number",
            "format": "double"
          },
          "candidateLimit": {
            "type": "integer",
            "format": "int32"
          },
          "resultCap": {
            "type": "integer",
            "format": "int32"
          },
          "dobYearTolerance": {
            "type": "integer",
            "format": "int32"
          },
          "dobMismatchPenalty": {
            "type": "number",
            "format": "double"
          },
          "dobMismatchSurfacing": {
            "type": "string",
            "description": "🟡 PROVISIONAL (#368). Strategy for surfacing a name hit whose DoB differs beyond\r\n            tolerance, on the wire as a readable string — `\"StrictExactName\"` (default) or\r\n            `\"HighScore\"`, case-insensitive (mirrors `SanctionsUnconfirmedDecision`; a raw enum\r\n            ordinal like `\"1\"` is rejected). NOT `required` (unlike the other knobs): the feature is\r\n            provisional and its safe default is StrictExactName, so an existing client that omits it keeps the\r\n            historical behaviour rather than getting a 400. See AMLService.Domain.Screening.DobMismatchSurfacing.",
            "nullable": true
          },
          "dobMismatchHighScoreThreshold": {
            "type": "number",
            "description": "🟡 PROVISIONAL (#368). Under HighScore surfacing, the provider score (0-1) a partial-name\r\n            DoB-mismatch must reach to surface for review. Non-required; defaults to 0.97 (the near-exact bar).",
            "format": "double"
          },
          "enabledLists": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Watchlists to screen against; empty = all lists.",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "basePresetKey": {
            "type": "string",
            "description": "Optional — records which system preset this profile was seeded from (display-only).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Create / update body for a named matching profile."
      },
      "MatchingProfilesResponse": {
        "required": [
          "presets",
          "profiles"
        ],
        "type": "object",
        "properties": {
          "profiles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MatchingProfileDto"
            },
            "nullable": true
          },
          "presets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MatchingPresetDto"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The tenant's saved profiles plus the system presets they can create from / reset to."
      },
      "MeResponse": {
        "type": "object",
        "properties": {
          "tenantId": {
            "type": "string",
            "format": "uuid"
          },
          "tenantName": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "creditBalance": {
            "type": "integer",
            "format": "int32"
          },
          "creditCostPerScreen": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "The caller's own tenant context. Credits are shown only when CreditCostPerScreen > 0."
      },
      "MonitoredSubjectResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "userReference": {
            "type": "string",
            "nullable": true
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "dateOfBirth": {
            "type": "string",
            "nullable": true
          },
          "nationality": {
            "type": "string",
            "nullable": true
          },
          "requestedLists": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "lastIsMatch": {
            "type": "boolean"
          },
          "lastRiskScore": {
            "type": "integer",
            "format": "int32"
          },
          "lastDecision": {
            "type": "string",
            "nullable": true
          },
          "lastScreenedAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "A monitored subject as returned to its owning tenant."
      },
      "OnboardTenantRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "slug": {
            "type": "string",
            "nullable": true
          },
          "contactEmail": {
            "type": "string",
            "nullable": true
          },
          "plan": {
            "type": "string",
            "nullable": true
          },
          "enabledLists": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Watchlists to screen against. Defaults to UN + EU if omitted.",
            "nullable": true
          },
          "defaultFuzzyThreshold": {
            "type": "number",
            "description": "Default fuzzy-match threshold (0-1). Defaults to the Recall-first preset (0.70) if omitted.",
            "format": "double",
            "nullable": true
          },
          "webhookUrl": {
            "type": "string",
            "description": "Optional callback URL; when present a signing secret is generated.",
            "nullable": true
          },
          "monthlyScreeningQuota": {
            "type": "integer",
            "description": "Optional monthly screening quota (fair-use / billing cap). Null = unlimited.",
            "format": "int32",
            "nullable": true
          },
          "rateLimitPerMinute": {
            "type": "integer",
            "description": "Optional per-minute screening rate limit (throughput / burst cap). Null = unlimited.",
            "format": "int32",
            "nullable": true
          },
          "liveApiKey": {
            "type": "boolean",
            "description": "Whether the tenant's first API key is a production (`aml_live_`) key. True for the admin\r\nonboarding path. Anonymous self-service registration sets this FALSE so the open endpoint can\r\nonly ever mint a sandbox (`aml_test_`) credential."
          },
          "brandDisplayName": {
            "type": "string",
            "description": "Optional white-label branding (display name / logo URL / hex accent colour).",
            "nullable": true
          },
          "brandLogoUrl": {
            "type": "string",
            "nullable": true
          },
          "brandAccentColor": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Inputs the onboarding wizard collects, sent as ONE call to POST /v1/tenants."
      },
      "OnboardTenantResponse": {
        "type": "object",
        "properties": {
          "tenantId": {
            "type": "string",
            "format": "uuid"
          },
          "apiKey": {
            "type": "string",
            "nullable": true
          },
          "webhookSigningSecret": {
            "type": "string",
            "nullable": true
          },
          "enabledLists": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "plan": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Onboarding result. The api_key and webhook_signing_secret are shown ONCE."
      },
      "OpenSanctionsMatchRequest": {
        "type": "object",
        "properties": {
          "config": {
            "type": "object",
            "additionalProperties": { },
            "description": "Algorithm-specific configuration object.",
            "nullable": true
          },
          "weights": {
            "type": "object",
            "additionalProperties": {
              "type": "number",
              "format": "double",
              "nullable": true
            },
            "nullable": true
          },
          "queries": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/MatchQuery"
            },
            "description": "Batch of example entities to match.\r\nKeys (\"entity1\", \"entity2\", …) are arbitrary IDs\r\nyou can correlate in the response.",
            "nullable": true
          },
          "limit": {
            "type": "integer",
            "description": "Max number of results to return per query (default 5, max 500).",
            "format": "int32",
            "nullable": true
          },
          "threshold": {
            "type": "number",
            "description": "Minimum score (0-1) for a match to be returned. Default 0.7.",
            "format": "double",
            "nullable": true
          },
          "algorithm": {
            "type": "string",
            "description": "Scoring algorithm (logic-v1, logic-v2, name-based, name-qualified, regression-v1).\r\nDefault is \"logic-v1\".",
            "nullable": true
          },
          "include_dataset": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Only include these dataset slugs in results.",
            "nullable": true
          },
          "exclude_schema": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Exclude these entity schemas (e.g. \"Company\", \"Vessel\").",
            "nullable": true
          },
          "exclude_dataset": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Exclude these dataset slugs from results.",
            "nullable": true
          },
          "topics": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Only return results matching any of the given topics.",
            "nullable": true
          },
          "exclude_entity_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Exclude specific entity IDs (max 50).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Root payload for POST /match/{dataset}"
      },
      "OpenSanctionsMatchResponse": {
        "type": "object",
        "properties": {
          "responses": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/MatchResponseItem"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PepRowDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The entity's stable internal id (GUID).",
            "nullable": true
          },
          "primaryName": {
            "type": "string",
            "description": "Canonical display name.",
            "nullable": true
          },
          "nationalities": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Nationalities / citizenships as held on the source (may be empty).",
            "nullable": true
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Office-category slugs this entity was captured under (minister, member-of-\r\n            parliament, head-of-state, relative, …); may be empty for a bundled PEP with no office scope.",
            "nullable": true
          },
          "pepTier": {
            "type": "string",
            "description": "Derived tier name (#231): National, Regional, Local, SOE, LocalGovernment,\r\n            Associates, or Unknown.",
            "nullable": true
          },
          "jurisdiction": {
            "type": "string",
            "description": "ISO alpha-2 of the office jurisdiction driving the tier, or null.",
            "nullable": true
          },
          "sourceList": {
            "type": "string",
            "description": "Originating list (always WIKIDATA here).",
            "nullable": true
          },
          "externalId": {
            "type": "string",
            "description": "The source id (the Wikidata QID).",
            "nullable": true
          },
          "sourceUrl": {
            "type": "string",
            "description": "Wikidata deep link when the external id is a Q-number, else null.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One row of the full PEP catalog: a Wikidata politically-exposed-person entity, with the office\r\ncategories it was captured under, its derived PEP tier (customer-relative Domestic/Foreign applied\r\nfrom the tenant's home jurisdiction) and its jurisdiction, plus a deep link back to the Wikidata\r\nsource record. Raw data — the UI is built separately against this exact shape."
      },
      "PepsPage": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PepRowDto"
            },
            "nullable": true
          },
          "total": {
            "type": "integer",
            "format": "int32"
          },
          "page": {
            "type": "integer",
            "format": "int32"
          },
          "pageSize": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "A page of the full PEP catalog. AMLService.Application.Peps.PepsPage.Total counts every entity matching the\r\n            filters (before paging)."
      },
      "PostScreeningFindingResponse": {
        "type": "object",
        "properties": {
          "checkKey": {
            "type": "string",
            "nullable": true
          },
          "outcome": {
            "type": "string",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One post-screening transparency finding surfaced on a matched entity (OPR-4b/5): a validation\r\ncheck fired on the match, with the outcome it drove and the human-readable reason. The wire shape\r\nof a `MatchFinding`, also the shape persisted in `MatchedEntity.PostScreeningFindingsJson`."
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": { }
      },
      "QuotaUsageResponse": {
        "type": "object",
        "properties": {
          "monthlyScreeningQuota": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "used": {
            "type": "integer",
            "format": "int32"
          },
          "remaining": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "period": {
            "type": "string",
            "nullable": true
          },
          "rateLimitPerMinute": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "requestsLastMinute": {
            "type": "integer",
            "format": "int32"
          },
          "creditBalance": {
            "type": "integer",
            "format": "int32"
          },
          "creditCostPerScreen": {
            "type": "integer",
            "format": "int32"
          },
          "demoIpRateLimitPerHour": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "maxBatchRows": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A tenant's current screening usage against its limits (monthly quota + per-minute rate)."
      },
      "RecordConsentRequest": {
        "type": "object",
        "properties": {
          "subjectReference": {
            "type": "string",
            "nullable": true
          },
          "consentVersion": {
            "type": "string",
            "nullable": true
          },
          "consentText": {
            "type": "string",
            "nullable": true
          },
          "channel": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RecordTurnoverEventRequest": {
        "type": "object",
        "properties": {
          "subjectReference": {
            "type": "string",
            "description": "The consumer's stable subject id (their own customer / user reference). Required.",
            "nullable": true
          },
          "amount": {
            "type": "number",
            "description": "The turnover amount for this event (non-negative). Required.",
            "format": "double"
          },
          "currency": {
            "type": "string",
            "description": "ISO 4217 currency code (e.g. EUR). Required; same-currency accumulation per subject.",
            "nullable": true
          },
          "occurredAt": {
            "type": "string",
            "description": "When the turnover occurred. Optional; defaults to now (UTC) when omitted.",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of POST /v1/threshold/events. The tenant is taken from the authenticated principal, never\r\nfrom this body. Records one turnover event for a subject and recomputes its rolling window."
      },
      "RectifySubjectRequest": {
        "type": "object",
        "properties": {
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "dateOfBirth": {
            "type": "string",
            "nullable": true
          },
          "nationality": {
            "type": "string",
            "nullable": true
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RectifySubjectResponse": {
        "type": "object",
        "properties": {
          "subjectReference": {
            "type": "string",
            "nullable": true
          },
          "updatedScreeningId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "updated": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "RegisterRequest": {
        "type": "object",
        "properties": {
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "password": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RegisterResponse": {
        "type": "object",
        "properties": {
          "tenantId": {
            "type": "string",
            "format": "uuid"
          },
          "tenantName": {
            "type": "string",
            "nullable": true
          },
          "slug": {
            "type": "string",
            "nullable": true
          },
          "apiKey": {
            "type": "string",
            "nullable": true
          },
          "monthlyFreeScreenings": {
            "type": "integer",
            "format": "int32"
          },
          "plan": {
            "type": "string",
            "nullable": true
          },
          "loginVerificationSent": {
            "type": "boolean"
          },
          "keyClass": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The registration result. ApiKey is a sandbox (`aml_test_`) key — see\r\nKeyClass — and is shown ONCE."
      },
      "RelativeOfDto": {
        "type": "object",
        "properties": {
          "qid": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The leader this relative is linked to (Wikidata QID + display name), for a PEP4 row."
      },
      "ResetToPresetRequest": {
        "type": "object",
        "properties": {
          "presetKey": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body for the reset-to-preset endpoint."
      },
      "ReviewCaseRequest": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RiskFactorResponse": {
        "type": "object",
        "properties": {
          "category": {
            "type": "string",
            "nullable": true
          },
          "sourceList": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          },
          "contribution": {
            "type": "number",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "An adverse match's weighted contribution to the risk score, for explainability."
      },
      "RiskProfileDto": {
        "required": [
          "allowLowBandPass",
          "candidateLimit",
          "categoryWeights",
          "countryWeights",
          "criminalWeight",
          "defaultFuzzyThreshold",
          "dobMismatchPenalty",
          "dobYearTolerance",
          "enabledLists",
          "escalateHighBandToFail",
          "exactMatch",
          "highThreshold",
          "lowThreshold",
          "mediumThreshold",
          "nicknamesEnabled",
          "phoneticEnabled",
          "resultCap",
          "trigramFloor"
        ],
        "type": "object",
        "properties": {
          "countryWeights": {
            "type": "object",
            "additionalProperties": {
              "type": "number",
              "format": "double"
            },
            "nullable": true
          },
          "categoryWeights": {
            "type": "object",
            "additionalProperties": {
              "type": "number",
              "format": "double"
            },
            "nullable": true
          },
          "criminalWeight": {
            "type": "number",
            "description": "Weight applied to `criminal`-category matches. This is an ACTIVE control: it fires for\r\nterrorism matches derived from a sanctions entity's terrorism programs (OFAC SDGT/SDT/FTO and the\r\nEU/UK/UN terrorism regimes — bundled), and for hits from a tenant's own bring-your-own\r\ncriminal-records feed. It does NOT synthesize a general criminal-records signal from the bundled\r\nsanctions/PEP corpus — we deliberately buy no general criminal-records data — so a bundled-only\r\ntenant sees this weight act on terrorism, and general criminal exposure needs a BYO feed.",
            "format": "double"
          },
          "lowThreshold": {
            "type": "integer",
            "format": "int32"
          },
          "mediumThreshold": {
            "type": "integer",
            "format": "int32"
          },
          "highThreshold": {
            "type": "integer",
            "format": "int32"
          },
          "enabledLists": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "defaultFuzzyThreshold": {
            "type": "number",
            "format": "double"
          },
          "homeJurisdiction": {
            "type": "string",
            "description": "The tenant's home country as an ISO alpha-2 code (e.g. \"CY\"). #231: the PEP tier is now\r\n            home-country-independent, so this no longer grades Domestic-vs-Foreign; it is retained as tenant\r\n            metadata (and for any non-tier use).",
            "nullable": true
          },
          "coveragePreset": {
            "type": "string",
            "description": "The selected coverage preset key, or `custom` when the coverage fields were tuned\r\n            directly. Set by the apply-preset action; also returned so the UI can show the active preset.",
            "nullable": true
          },
          "pepTierFilter": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Allowed PEP tier names (empty = every tier); PEP matches outside this set are excluded.",
            "nullable": true
          },
          "maxDataAgeDays": {
            "type": "integer",
            "description": "Optional data-freshness window (days): only match watchlist data seen within this many\r\n            days. Null = no filter (use all data).",
            "format": "int32",
            "nullable": true
          },
          "escalateHighBandToFail": {
            "type": "boolean"
          },
          "allowLowBandPass": {
            "type": "boolean"
          },
          "pepMatchFloorsToReview": {
            "type": "boolean",
            "description": "When true (the default), a confirmed PEP match floors the decision to at least Review — it can never\r\nsilently Pass, whatever the band or adverse-media availability (OPR-4b/5). A tenant sets this false\r\nto allow a low-band PEP to Pass. Not required on input so existing admin clients that omit it keep\r\nthe safe default; absent input is read as the default-on posture."
          },
          "phoneticEnabled": {
            "type": "boolean",
            "description": "Whether phonetic (dmetaphone) candidate widening is enabled for this tenant."
          },
          "exactMatch": {
            "type": "boolean",
            "description": "Whether the matcher favours exact over fuzzy matching by default."
          },
          "nicknamesEnabled": {
            "type": "boolean",
            "description": "Whether nickname/hypocorism query expansion is enabled for this tenant."
          },
          "trigramFloor": {
            "type": "number",
            "description": "pg_trgm similarity floor for trigram candidate retrieval (0-1).",
            "format": "double"
          },
          "candidateLimit": {
            "type": "integer",
            "description": "Maximum candidates pulled per query during retrieval.",
            "format": "int32"
          },
          "resultCap": {
            "type": "integer",
            "description": "Maximum scored matches returned after ranking.",
            "format": "int32"
          },
          "dobYearTolerance": {
            "type": "integer",
            "description": "DoB year tolerance (± years) within which two years of birth are not a mismatch.",
            "format": "int32"
          },
          "dobMismatchPenalty": {
            "type": "number",
            "description": "Score penalty when years of birth differ beyond the tolerance (0-1).",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "The tenant's risk profile as returned to / accepted from an admin."
      },
      "SanctionCase": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "dob": {
            "type": "string",
            "nullable": true
          },
          "gender": {
            "type": "string",
            "nullable": true
          },
          "citizenship": {
            "type": "string",
            "nullable": true
          },
          "nationality": {
            "type": "string",
            "nullable": true
          },
          "phoneNumber": {
            "type": "string",
            "nullable": true
          },
          "emailAddress": {
            "type": "string",
            "nullable": true
          },
          "cryptoId": {
            "type": "string",
            "nullable": true
          },
          "address": {
            "$ref": "#/components/schemas/Address"
          },
          "identification": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Identification"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SanctionsPolicyResponse": {
        "type": "object",
        "properties": {
          "unconfirmedSanctionsDecision": {
            "type": "string",
            "description": "The stored posture (\"Review\" or \"Fail\").",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Echoes a tenant's persisted unconfirmed-sanctions posture after a write."
      },
      "SanctionsScreeningRequest": {
        "type": "object",
        "properties": {
          "apiKey": {
            "type": "string",
            "nullable": true
          },
          "minScore": {
            "type": "integer",
            "format": "int32"
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "types": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "cases": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SanctionCase"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SanctionsSearchRequest": {
        "type": "object",
        "properties": {
          "apiKey": {
            "type": "string",
            "nullable": true
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "types": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "cases": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CaseDto"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ScreeningCheckRequest": {
        "type": "object",
        "properties": {
          "subjectId": {
            "type": "string",
            "description": "Screen a subject already registered via `POST /v1/subjects`, instead of sending identity\r\ndetails inline. Optional — omit it and this request behaves exactly as it always has.",
            "format": "uuid",
            "nullable": true
          },
          "userReference": {
            "type": "string",
            "description": "Caller's own correlation reference (e.g. their customer id).",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "description": "Given name(s). Optional convenience alternative to AMLService.Application.Screening.ScreeningCheckRequest.FullName (#369): supply\r\nAMLService.Application.Screening.ScreeningCheckRequest.FirstName + AMLService.Application.Screening.ScreeningCheckRequest.LastName and the server composes AMLService.Application.Screening.ScreeningCheckRequest.FullName from\r\nthem. An explicit non-blank AMLService.Application.Screening.ScreeningCheckRequest.FullName always takes precedence — see\r\nAMLService.Application.Screening.ApplicantName. Validation requires at least one of {AMLService.Application.Screening.ScreeningCheckRequest.FullName,\r\n(AMLService.Application.Screening.ScreeningCheckRequest.FirstName + AMLService.Application.Screening.ScreeningCheckRequest.LastName)} unless AMLService.Application.Screening.ScreeningCheckRequest.SubjectId is given.",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "description": "Family name. See AMLService.Application.Screening.ScreeningCheckRequest.FirstName; the two are composed into AMLService.Application.Screening.ScreeningCheckRequest.FullName\r\n            only when no explicit AMLService.Application.Screening.ScreeningCheckRequest.FullName was supplied.",
            "nullable": true
          },
          "fullName": {
            "type": "string",
            "description": "Full name of the person to screen. Required unless AMLService.Application.Screening.ScreeningCheckRequest.SubjectId is given, OR\r\n            AMLService.Application.Screening.ScreeningCheckRequest.FirstName + AMLService.Application.Screening.ScreeningCheckRequest.LastName are supplied (from which this is composed).",
            "nullable": true
          },
          "dateOfBirth": {
            "type": "string",
            "description": "Date of birth, ISO yyyy-MM-dd (or yyyy). Optional.",
            "nullable": true
          },
          "nationality": {
            "type": "string",
            "description": "Nationality as an ISO country code. Optional.",
            "nullable": true
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Known aliases / alternate spellings.",
            "nullable": true
          },
          "lists": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Watchlists to screen against. Recorded for audit; null = provider default.",
            "nullable": true
          },
          "threshold": {
            "type": "number",
            "description": "Match threshold 0-1. Falls back to a default when omitted.",
            "format": "double",
            "nullable": true
          },
          "exactMatch": {
            "type": "boolean",
            "description": "Favour exact over fuzzy matching.",
            "nullable": true
          },
          "phonetic": {
            "type": "boolean",
            "description": "Per-request phonetic (dmetaphone) widening override; `null` uses the tenant default.",
            "nullable": true
          },
          "nicknames": {
            "type": "boolean",
            "description": "Per-request nickname/hypocorism expansion override; `null` uses the tenant default.",
            "nullable": true
          },
          "trigramFloor": {
            "type": "number",
            "description": "Per-request pg_trgm trigram floor override (0-1); `null` uses the tenant default.",
            "format": "double",
            "nullable": true
          },
          "candidateLimit": {
            "type": "integer",
            "description": "Per-request candidate-retrieval limit override; `null` uses the tenant default.",
            "format": "int32",
            "nullable": true
          },
          "resultCap": {
            "type": "integer",
            "description": "Per-request result-cap override; `null` uses the tenant default.",
            "format": "int32",
            "nullable": true
          },
          "dobYearTolerance": {
            "type": "integer",
            "description": "Per-request DoB year-tolerance override (± years); `null` uses the tenant default.",
            "format": "int32",
            "nullable": true
          },
          "dobMismatchPenalty": {
            "type": "number",
            "description": "Per-request DoB year-mismatch penalty override (0-1); `null` uses the tenant default.",
            "format": "double",
            "nullable": true
          },
          "dobMismatchSurfacing": {
            "$ref": "#/components/schemas/DobMismatchSurfacing"
          },
          "dobMismatchHighScoreThreshold": {
            "type": "number",
            "description": "🟡 PROVISIONAL (#368). Per-request override for the HighScore surfacing threshold (0-1);\r\n            `null` uses the tenant default (0.97).",
            "format": "double",
            "nullable": true
          },
          "monitor": {
            "type": "boolean",
            "description": "When true, enrol this subject for ongoing monitoring (re-screened on list changes).",
            "nullable": true
          },
          "enhancedDueDiligence": {
            "type": "boolean",
            "description": "Per-screen Enhanced Due Diligence toggle for the post-screening validation framework (OPR-4b/5).\r\n`null` uses the tenant's `EnhancedDueDiligenceDefault`; `true` puts this screen\r\nunder EDD (the higher-risk Associates PEP exposure escalates to Fail — #231);\r\n`false` screens it under the baseline posture regardless of the tenant default.",
            "nullable": true
          },
          "pepTiers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Optional PEP-tier allow-list: when non-empty, PEP matches whose tier is not in this set are\r\nexcluded from the result and do not drive the decision (e.g. `[\"National\",\"Regional\"]`\r\nto ignore lower-tier PEPs). Accepts the #231 tier names National / Regional / Local / SOE /\r\nLocalGovernment / Associates (case-insensitive). Null/empty screens every tier (no filter). Sanctions\r\nand adverse-media matches are never affected.",
            "nullable": true
          },
          "coveragePreset": {
            "type": "string",
            "description": "Optional coverage preset key for THIS screen (`comprehensive` / `balanced` /\r\n`sanctions-only` / `enhanced-pep`) — overrides the tenant's default lists + PEP-level\r\nscope for one screen. An explicit AMLService.Application.Screening.ScreeningCheckRequest.Lists / AMLService.Application.Screening.ScreeningCheckRequest.PepTiers on the request still\r\nwins over the preset. Null/unknown = use the tenant's stored coverage. See\r\nAMLService.Application.Screening.ScreeningCheckRequest.CoveragePreset.",
            "nullable": true
          },
          "maxDataAgeDays": {
            "type": "integer",
            "description": "Optional per-screen data-freshness window (days): only count watchlist entities last\r\n            seen within this many days. Overrides the tenant default; null = use the tenant setting.",
            "format": "int32",
            "nullable": true
          },
          "adverseMedia": {
            "type": "boolean",
            "description": "Per-request adverse-media toggle. `null` uses the tenant/global default; `false` skips\r\nthe adverse-media (news) check for this screen — much faster, sanctions/PEP still run; `true`\r\nruns it when an adverse-media source is configured. Adverse media adds a live news query, so\r\ncallers that only need sanctions/PEP can switch it off for low latency.",
            "nullable": true
          },
          "includeDiagnostics": {
            "type": "boolean",
            "description": "When true, the response includes a `diagnostics` object with the per-screen timing\r\nbreakdown (total / candidate-match / classify / risk / persist ms) + counts — handy for\r\nlatency debugging and for AI agents that want the metrics inline. Off by default (no overhead).",
            "nullable": true
          },
          "includeReasoning": {
            "type": "boolean",
            "description": "When true, the response includes a `reason` object (DM-6 / #235) explaining WHY the screen\r\nreached its Pass / Review / Fail decision — a machine-readable reason code plus a one-line summary,\r\nthe driving category / evidence tier, and (for a PEP) its class. Off by default (mirrors\r\nAMLService.Application.Screening.ScreeningCheckRequest.IncludeDiagnostics): reasoning is opt-in and adds ZERO cost when off — it is derived\r\npurely from data the screen already computed, with no extra query and no scoring. The portal sends\r\n`true` by default so an analyst always sees the explanation; lean external callers omit it.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of POST /v1/screenings/check. The tenant is taken from the authenticated\r\nprincipal, never from this body."
      },
      "ScreeningDiagnostics": {
        "type": "object",
        "properties": {
          "totalMs": {
            "type": "integer",
            "format": "int64"
          },
          "candidateMatchMs": {
            "type": "integer",
            "format": "int64"
          },
          "classifyMs": {
            "type": "integer",
            "format": "int64"
          },
          "riskMs": {
            "type": "integer",
            "format": "int64"
          },
          "persistMs": {
            "type": "integer",
            "format": "int64"
          },
          "providersRun": {
            "type": "integer",
            "format": "int32"
          },
          "matchCount": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Per-screen timing + count metrics, returned only when the request sets `includeDiagnostics`.\r\nMachine-readable (fixed keys, integer milliseconds) so callers — including AI agents — can read the\r\nlatency breakdown straight from the screen response without a separate metrics call. The same\r\nnumbers are emitted as a structured log line on every screen."
      },
      "ScreeningResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The screening's id. Use it with `GET /v1/screenings/{id}`; it is also the\r\n            `screeningId` carried by the `screening.completed` webhook.",
            "format": "uuid"
          },
          "isMatch": {
            "type": "boolean",
            "description": "Whether any match was found at all."
          },
          "score": {
            "type": "number",
            "description": "The highest match score across the visible matches (0..1).",
            "format": "double"
          },
          "classification": {
            "type": "string",
            "description": "#380: the screening's TOP category — `sanctions` / `pep` /\r\n            `adverse_media` (or `criminal`), taken from the top-ranked `factors[].category`, or the\r\n            clean value `clear` when nothing matched. This is the CATEGORY of the hit, NOT the match\r\n            confidence — the confidence moved to AMLService.Application.Screening.ScreeningResponse.MatchConfidence.",
            "nullable": true
          },
          "decision": {
            "type": "string",
            "description": "The aggregate verdict: `Pass`, `Review` or `Fail`. Final —\r\n            it never changes after this response.",
            "nullable": true
          },
          "riskScore": {
            "type": "integer",
            "description": "The risk engine's 0-100 score for this screening. Final.",
            "format": "int32"
          },
          "riskBand": {
            "type": "string",
            "description": "The band the score falls in: `Minimal` / `Low` / `Medium` /\r\n            `High`.",
            "nullable": true
          },
          "matchedEntities": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MatchedEntityResponse"
            },
            "description": "The VISIBLE matches — the ones that drove the decision. This is what\r\n            the webhook's `matchCount` counts; deceased-suppressed matches are not in here and are not\r\n            counted there.",
            "nullable": true
          },
          "factors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RiskFactorResponse"
            },
            "description": "Per-match weighted contributions to the risk score, for explainability.",
            "nullable": true
          },
          "listsVersion": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "The watchlist versions PINNED at the moment this screen ran — the corpus\r\n            the decision was actually made against.",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "description": "When the screening ran.",
            "format": "date-time"
          },
          "diagnostics": {
            "$ref": "#/components/schemas/ScreeningDiagnostics"
          },
          "adverseMediaStatus": {
            "type": "string",
            "description": "Whether the adverse-media stage actually RAN, and if not why:\r\n            `Skipped` (opted out or feature off — we did not look), `Ok` (the source answered, so an\r\n            empty media result genuinely means clean), `Stale` (the source was down and a cached lookup was\r\n            served, so evidence may be out of date), `Unavailable` (the source was down with no cache —\r\n            ADVERSE MEDIA WAS NOT CHECKED). A caller MUST NOT read an empty media result as \"clean\" when this is\r\n            `Unavailable`: it is an incomplete screen, not a pass.",
            "nullable": true
          },
          "adverseMediaAttribution": {
            "type": "string",
            "description": "Attribution required by the source's terms of use wherever\r\n            media results are shown. Non-null only when this screen carries adverse-media results.",
            "nullable": true
          },
          "suppressedDeceasedCount": {
            "type": "integer",
            "description": "COV-12: how many matches were HIDDEN from\r\n            `matchedEntities` by the tenant's deceased-hide policy (the length of\r\n            `suppressedMatches`). 0 when nothing was hidden. NOT added into the webhook's\r\n            `matchCount`, because the decision excluded these too.",
            "format": "int32"
          },
          "suppressedMatches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MatchedEntityResponse"
            },
            "description": "COV-12: the matches hidden by the deceased-hide policy — same shape\r\n            as `matchedEntities`, each carrying its `deceased` block, so the UI can REVEAL them\r\n            on demand. Excluded from the decision and the visible list. Null / empty when nothing was hidden.\r\n            They appear on this synchronous response only; the webhook never carries them.",
            "nullable": true
          },
          "tenantDeceasedConfig": {
            "$ref": "#/components/schemas/DeceasedConfigResponse"
          },
          "reason": {
            "$ref": "#/components/schemas/DecisionReasonResponse"
          },
          "correlationId": {
            "type": "string",
            "description": "WI-382: the tracing key for the call that produced this response — the\r\n            value of the request's `X-Correlation-Id` header when the caller supplied one, otherwise the one\r\n            the service generated for the request. Echoed here in the BODY (as well as on the `X-Correlation-Id`\r\n            response header), and carried on the `screening.completed` webhook as `correlationId`, so a\r\n            delivered webhook can be tied back to the originating call and either side can quote one id when\r\n            investigating a specific case. Always present on a live response; null only on a legacy/synthetic\r\n            response built outside the request pipeline.",
            "nullable": true
          },
          "matchConfidence": {
            "type": "string",
            "description": "#380: the match-confidence value that `classification` USED to\r\n            carry — `Unknown` / `PotentialMatch` / `TruePositive` (the top match's\r\n            `MatchClassification`). Split out under its own name so the confidence is preserved now that\r\n            AMLService.Application.Screening.ScreeningResponse.Classification reports the category instead. `Unknown` on a clean screen.",
            "nullable": true
          },
          "reasonCodes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "#379 (§6 / FR-7 / FR-8): the coarse MVP reason codes derived from the\r\n            screen's factor categories — a distinct, deterministically-ordered subset of\r\n            { `SANCTIONS`, `PEP`, `ADVERSE_MEDIA`, `TERRORISM` }. Empty on a clean screen.\r\n            `criminal` maps to `TERRORISM` as a deliberate approximation — see\r\n            AMLService.Application.Screening.ScreeningReasonCodes.",
            "nullable": true
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SourceStatusResponse"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The FINAL result of one screening, persisted as an immutable audit record.\r\n            \r\n\nThis is the complete body of the synchronous `201` from `POST /v1/screenings/check`,\r\nand the same shape `GET /v1/screenings/{id}` returns later. It carries no progress or status\r\nfield because there is no asynchronous work behind it: the verdict here is the verdict, and no\r\nbackground process revises `decision`, `riskScore` or the matches\r\nafterwards. Only an analyst's disposition overlay and the retention purge ever touch the record\r\nagain."
      },
      "ScreeningSearchItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "decision": {
            "type": "string",
            "nullable": true
          },
          "riskScore": {
            "type": "integer",
            "format": "int32"
          },
          "isMatch": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "rank": {
            "type": "number",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "One ranked row in the search result."
      },
      "ScreeningSearchResponse": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ScreeningSearchItem"
            },
            "nullable": true
          },
          "total": {
            "type": "integer",
            "format": "int32"
          },
          "skip": {
            "type": "integer",
            "format": "int32"
          },
          "take": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "A page of ranked search hits plus the total count for the query."
      },
      "ScreeningStats": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "format": "int32"
          },
          "matches": {
            "type": "integer",
            "format": "int32"
          },
          "last24Hours": {
            "type": "integer",
            "format": "int32"
          },
          "last7Days": {
            "type": "integer",
            "format": "int32"
          },
          "byDecision": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CountByLabel"
            },
            "nullable": true
          },
          "byRiskBand": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CountByLabel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Screening volume, outcome breakdowns, and recency windows."
      },
      "ServiceOverMaxMethodConfig": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "maxYears": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Method 3 (`service_over_max`, presumed): on/off + the since-office ceiling in years."
      },
      "SetBatchConfigRequest": {
        "type": "object",
        "properties": {
          "maxBatchRows": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Admin request to set a tenant's per-batch-upload row cap. Null clears it (unlimited —\r\n            the default; a batch is then bounded only by the global engine cap)."
      },
      "SetBrandingRequest": {
        "type": "object",
        "properties": {
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "logoUrl": {
            "type": "string",
            "nullable": true
          },
          "accentColor": {
            "type": "string",
            "nullable": true
          },
          "secondaryColor": {
            "type": "string",
            "nullable": true
          },
          "surfaceColor": {
            "type": "string",
            "nullable": true
          },
          "textColor": {
            "type": "string",
            "nullable": true
          },
          "fontFamily": {
            "type": "string",
            "nullable": true
          },
          "cornerRadius": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Admin request to set a tenant's white-label branding. Any field omitted/null is cleared."
      },
      "SetCreditsRequest": {
        "type": "object",
        "properties": {
          "creditBalance": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "creditCostPerScreen": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Admin request to top up a tenant's credit balance and/or set its per-screen cost.\r\n            Each field is optional — omit one to leave it unchanged. Cost 0 = credits not enforced (free)."
      },
      "SetDeceasedConfigRequest": {
        "type": "object",
        "properties": {
          "hideDeceased": {
            "type": "boolean"
          },
          "deathDate": {
            "$ref": "#/components/schemas/DeathDateMethodConfig"
          },
          "ageOverMax": {
            "$ref": "#/components/schemas/AgeOverMaxMethodConfig"
          },
          "serviceOverMax": {
            "$ref": "#/components/schemas/ServiceOverMaxMethodConfig"
          }
        },
        "additionalProperties": false,
        "description": "The `PUT /v1/tenants/me/deceased-config` body — the SAME shape as\r\nAMLService.Application.Screening.DeceasedConfigResponse so a client can read, edit, and write back the identical object."
      },
      "SetDemoIpRateLimitRequest": {
        "type": "object",
        "properties": {
          "requestsPerHour": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Admin request to set the demo tenant's per-IP screening cap (per hour). Null clears it\r\n            (the per-IP demo cap is disabled)."
      },
      "SetMonitoringConfigRequest": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "nullable": true
          },
          "cadenceDaysOverride": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Set the tenant's monitoring switch (required) and optional daily-cadence override (days)."
      },
      "SetQuotaRequest": {
        "type": "object",
        "properties": {
          "monthlyScreeningQuota": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Admin request to set a tenant's monthly screening quota. Null clears it (unlimited)."
      },
      "SetRateLimitRequest": {
        "type": "object",
        "properties": {
          "requestsPerMinute": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Admin request to set a tenant's per-minute screening rate limit. Null clears it (unlimited)."
      },
      "SetSanctionsPolicyRequest": {
        "type": "object",
        "properties": {
          "unconfirmedSanctionsDecision": {
            "type": "string",
            "description": "\"Review\" (default) or \"Fail\" (strict). Case-insensitive.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Admin request to set a tenant's posture for an <b>unconfirmed</b> sanctions hit. Accepts a readable\r\nstring — `\"Review\"` (the permissive-but-reviewed default: a no-DOB partial-name overlap goes to a\r\nhuman) or `\"Fail\"` (strict: block on any possible sanctions hit until cleared). Case-insensitive.\r\nA <i>confirmed</i> sanctions hit (exact full-DOB agreement) always fails and is never governed by this."
      },
      "SetTenantStatusRequest": {
        "type": "object",
        "properties": {
          "active": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Enable (true) or disable (false) a tenant."
      },
      "SetThresholdConfigRequest": {
        "type": "object",
        "properties": {
          "threshold": {
            "type": "number",
            "description": "Rolling-window turnover that triggers an auto re-screen. Null clears the config.",
            "format": "double",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "description": "ISO 4217 currency the threshold is denominated in. Required when a threshold is set.",
            "nullable": true
          },
          "windowDays": {
            "type": "integer",
            "description": "Trailing window (days). Null falls back to the 30-day default.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Admin request to set (or clear) a tenant's turnover-threshold config. A null\r\nAMLService.Application.Threshold.SetThresholdConfigRequest.Threshold clears it (disables turnover monitoring — the feature goes inert)."
      },
      "SourceStatusResponse": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "#375: one screening/watchlist source's availability for a screen, on the wire. `status` is one\r\nof `ok` / `degraded` / `unavailable`. A screen is PARTIAL if ANY source is not\r\n`ok`; a clean result on a screen with an `unavailable` source is NOT proof of clearance on\r\nthat source — it was not consulted."
      },
      "StatsResponse": {
        "type": "object",
        "properties": {
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "watchlists": {
            "$ref": "#/components/schemas/WatchlistStats"
          },
          "screenings": {
            "$ref": "#/components/schemas/ScreeningStats"
          },
          "tenants": {
            "$ref": "#/components/schemas/TenantStats"
          },
          "recentRefreshes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WatchlistRefreshDto"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Platform-wide statistics returned by `GET /v1/admin/stats`. Admin-only; aggregates\r\nacross all tenants (the watchlist reference data is global, the screening / tenant counts\r\nare platform totals). Surfaced by the bundled dashboard at `/stats/index.html`."
      },
      "SubjectExportResponse": {
        "type": "object",
        "properties": {
          "subjectReference": {
            "type": "string",
            "nullable": true
          },
          "tenantId": {
            "type": "string",
            "format": "uuid"
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "screenings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExportScreening"
            },
            "nullable": true
          },
          "cases": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExportCase"
            },
            "nullable": true
          },
          "consents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExportConsent"
            },
            "nullable": true
          },
          "monitoring": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExportMonitoring"
            },
            "nullable": true
          },
          "flags": {
            "$ref": "#/components/schemas/ExportFlags"
          },
          "auditTrail": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExportAuditEntry"
            },
            "nullable": true
          },
          "requests": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExportRequest"
            },
            "nullable": true
          },
          "subjects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExportSubject"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A self-contained bundle of everything held for one subject under a tenant."
      },
      "SubjectFlagResponse": {
        "type": "object",
        "properties": {
          "subjectReference": {
            "type": "string",
            "nullable": true
          },
          "restricted": {
            "type": "boolean"
          },
          "objected": {
            "type": "boolean"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "SubjectRequest": {
        "type": "object",
        "properties": {
          "userReference": {
            "type": "string",
            "description": "Caller's own stable reference for this person (e.g. their customer id). Optional, but UNIQUE\r\nper tenant when set — see AMLService.Domain.Entities.Subject.UserReference for why sharing\r\none across two subjects is rejected rather than merged.",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "description": "Given name(s). Optional alternative to AMLService.Application.Subjects.SubjectRequest.FullName (#369): supply\r\n            AMLService.Application.Subjects.SubjectRequest.FirstName + AMLService.Application.Subjects.SubjectRequest.LastName and the server composes AMLService.Application.Subjects.SubjectRequest.FullName.\r\n            An explicit non-blank AMLService.Application.Subjects.SubjectRequest.FullName always wins.",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "description": "Family name. See AMLService.Application.Subjects.SubjectRequest.FirstName.",
            "nullable": true
          },
          "fullName": {
            "type": "string",
            "description": "Full name of the person. Required unless AMLService.Application.Subjects.SubjectRequest.FirstName + AMLService.Application.Subjects.SubjectRequest.LastName\r\n            are supplied (from which it is composed).",
            "nullable": true
          },
          "dateOfBirth": {
            "type": "string",
            "description": "Date of birth, ISO yyyy-MM-dd (or yyyy). Optional.",
            "nullable": true
          },
          "nationality": {
            "type": "string",
            "description": "Nationality as an ISO country code. Optional.",
            "nullable": true
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Known aliases / alternate spellings. Optional.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of POST /v1/subjects and PUT /v1/subjects/{id}. The tenant is taken from the authenticated\r\nprincipal, never from this body. PUT is a FULL replace: an omitted optional field clears it, so a\r\ncorrection cannot leave a stale nationality behind because the caller forgot to resend it."
      },
      "SubjectResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "userReference": {
            "type": "string",
            "nullable": true
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "dateOfBirth": {
            "type": "string",
            "nullable": true
          },
          "nationality": {
            "type": "string",
            "nullable": true
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastScreenedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A stored subject as returned to the caller. Identity only — no verdict, no monitoring baseline\r\nand no adverse-media evidence, because a subject is who you screen, not what was found.\r\nLastScreenedAt is null for a subject that has never been screened."
      },
      "TenantCoverageDto": {
        "type": "object",
        "properties": {
          "preset": {
            "type": "string",
            "nullable": true
          },
          "enabledLists": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "pepTiers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The tenant's active coverage: the selected preset key (or `custom`) + the resolved\r\n            lists and allowed PEP tiers."
      },
      "TenantMonitoringConfig": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "cadenceDaysOverride": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A tenant's ongoing-monitoring participation config: the on/off switch and an optional\r\n            per-tenant daily-cadence override (days; null = use the global cadence)."
      },
      "TenantStats": {
        "type": "object",
        "properties": {
          "totalTenants": {
            "type": "integer",
            "format": "int32"
          },
          "activeApiKeys": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Tenant and active-key totals."
      },
      "ThresholdConfigResponse": {
        "type": "object",
        "properties": {
          "threshold": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "nullable": true
          },
          "windowDays": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "enabled": {
            "type": "boolean"
          }
        },
        "additionalProperties": false,
        "description": "A tenant's current turnover-threshold config (null threshold = monitoring disabled)."
      },
      "ThresholdSubjectResponse": {
        "type": "object",
        "properties": {
          "subjectReference": {
            "type": "string",
            "nullable": true
          },
          "accumulatedTurnover": {
            "type": "number",
            "format": "double"
          },
          "currency": {
            "type": "string",
            "nullable": true
          },
          "windowDays": {
            "type": "integer",
            "format": "int32"
          },
          "threshold": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "breached": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "lastTriggeredAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "Current rolling-turnover ledger status for a subject (GET /v1/threshold/subjects/{ref})."
      },
      "TriggerableJobDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "isRunning": {
            "type": "boolean"
          },
          "latestRun": {
            "$ref": "#/components/schemas/JobRunDto"
          }
        },
        "additionalProperties": false,
        "description": "A job as the console sees it: its identity and description, whether it can be triggered on demand,\r\nand the provenance of its most recent run. This is what lets the UI show \"last run 09:14, succeeded,\r\ntriggered manually by …\" rather than just a green dot."
      },
      "TurnoverEventResult": {
        "type": "object",
        "properties": {
          "subjectReference": {
            "type": "string",
            "nullable": true
          },
          "windowTurnover": {
            "type": "number",
            "format": "double"
          },
          "threshold": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "nullable": true
          },
          "windowDays": {
            "type": "integer",
            "format": "int32"
          },
          "breached": {
            "type": "boolean"
          },
          "rescreenId": {
            "type": "string",
            "format": "uuid",
            "nullable": true
          },
          "rescreenSkippedReason": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Outcome of recording a turnover event: the recomputed rolling-window turnover, the effective\r\nthreshold, whether it is breached, and — when a breach auto-triggered an enhanced re-screen —\r\nthe new screening id. AMLService.Application.Threshold.TurnoverEventResult.RescreenSkippedReason explains a breach that could NOT be\r\nre-screened (e.g. no prior screening exists for the subject)."
      },
      "UiConfigResponse": {
        "type": "object",
        "properties": {
          "marketingUrl": {
            "type": "string",
            "description": "Absolute URL of the marketing site, or empty. Empty (the standalone default) tells the nav to hide\r\nthe marketing-hosted Home + Pricing items and point the brand link at the product root `/`.\r\nWhen set, the nav links brand/Home to it and Pricing to `MarketingUrl + \"#pricing\"`.",
            "nullable": true
          },
          "logoutUrl": {
            "type": "string",
            "description": "Absolute sign-out URL DERIVED from the deployment's own IdP configuration (the OIDC authority the\r\nbundled sign-in flow authenticates against), or empty when no authority is configured. Empty tells\r\nthe nav to fall back to a relative `/logout`, so sign-out never targets a non-existent host.",
            "nullable": true
          },
          "selfHosted": {
            "type": "boolean",
            "description": "Whether this instance is a self-hosted client appliance. When `true` the bundled UIs hide the\r\ncommercial/SaaS-only surfaces (credits + plan, the pay-per-screen line) and the public demo key is\r\nwithheld. DEFAULT `false` (commercial/SaaS) — see\r\nAMLService.Application.Deployment.DeploymentOptions.SelfHosted. It does NOT mean \"no v2 portal\": v2 ships to\r\nself-hosted clients too. Use V2ConsoleBaseUrl for that question."
          },
          "oidcAuthority": {
            "type": "string",
            "description": "The OIDC authority the bundled console pages sign in against (the SAME source the sign-out URL is\r\nderived from: the deployment's own IdP), WITHOUT a trailing slash so the JS can append\r\n`/connect/authorize` etc. Empty when no authority is configured — the JS then falls back to\r\nsame-origin so a config gap never leaves a user unable to sign in.",
            "nullable": true
          },
          "oidcClientId": {
            "type": "string",
            "description": "The OIDC (PKCE) client id the bundled console pages log in with (default `aml-admin-console`),\r\nso it is not hard-coded in served JS.",
            "nullable": true
          },
          "editionLabel": {
            "type": "string",
            "description": "A small, neutral edition badge text (e.g. `\"Self-Hosted Edition\"`) the bundled top-nav renders\r\nnext to the brand. NON-EMPTY only when the request arrived on a configured self-host showcase host\r\n(AMLService.Application.Branding.BrandingUiOptions.SelfHostHosts); EMPTY on every other host, so the commercial\r\nnav is unchanged. Purely presentational.",
            "nullable": true
          },
          "v2ConsoleBaseUrl": {
            "type": "string",
            "description": "Browser-reachable base of the v2 (React-Native) operator console: `/app` on EVERY edition, read\r\nstraight from AMLService.Application.Deployment.V2Console.BaseUrl — the same constant the server-side v1→v2\r\nredirect uses, so the nav and the redirect cannot disagree about where the console is.\r\n            \r\n\nIt is no longer host- or mode-dependent and is never empty. The old EMPTY value meant \"keep the\r\nnav on the bundled v1 pages\"; those pages were deleted in Wave B, so that value could now only ever\r\nproduce a 404. The field is retained in the contract because the bundled nav (`shared/topnav.js`,\r\nstill served on `/docs`, `/pricing` and `/register`) reads it.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Browser-facing configuration for the bundled static UI, served anonymously via\r\n`GET /v1/ui/config`. Exists so the bundled JS carries NO deployment-specific host or mode\r\nhard-coded in served JavaScript: ONE codebase serves both our commercial SaaS and a self-hosted\r\nclient appliance, correct without editing the JS or the distribution neutralise step rewriting hosts."
      },
      "UpsertExternalProviderRequest": {
        "required": [
          "enabled"
        ],
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "apiKey": {
            "type": "string",
            "description": "The tenant's provider API key. Omit to keep the existing stored key.",
            "nullable": true
          },
          "collection": {
            "type": "string",
            "nullable": true
          },
          "algorithm": {
            "type": "string",
            "nullable": true
          },
          "threshold": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "includeDatasets": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "topics": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "baseUrl": {
            "type": "string",
            "description": "The tenant's adverse-media endpoint. Required to enable an AdverseMedia provider.",
            "nullable": true
          },
          "keywords": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "maxRecords": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Admin request to create or update a tenant's external-provider config. The provider type\r\ncomes from the route. AMLService.Application.Screening.UpsertExternalProviderRequest.ApiKey is write-only: supply it to (re)set the tenant's\r\nkey; omit it to keep the stored key (e.g. when only toggling AMLService.Application.Screening.UpsertExternalProviderRequest.Enabled or tuning\r\nsettings). It is never returned by the API."
      },
      "ValidationProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "nullable": true
          },
          "errors": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "nullable": true
          }
        },
        "additionalProperties": { }
      },
      "WatchlistHealthResponse": {
        "type": "object",
        "properties": {
          "generatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WatchlistSourceHealth"
            },
            "nullable": true
          },
          "anySanctionsUnhealthy": {
            "type": "boolean",
            "description": "Any compliance-critical sanctions source is stale or failing — the RED daily-report line.",
            "readOnly": true
          },
          "unhealthyCount": {
            "type": "integer",
            "description": "Count of sources (any category) that are stale or failing.",
            "format": "int32",
            "readOnly": true
          },
          "overallSeverity": {
            "$ref": "#/components/schemas/WatchlistHealthSeverity"
          }
        },
        "additionalProperties": false,
        "description": "The per-source health summary for the whole shared corpus, plus roll-up flags the daily report and the\r\nconsole read to decide whether to shout."
      },
      "WatchlistHealthSeverity": {
        "enum": [
          0,
          1,
          2
        ],
        "type": "integer",
        "description": "How loudly a source's stale/failing state should surface. Ordered so a summary can take the max.",
        "format": "int32"
      },
      "WatchlistRefreshDto": {
        "type": "object",
        "properties": {
          "sourceList": {
            "type": "string",
            "nullable": true
          },
          "finishedAt": {
            "type": "string",
            "format": "date-time"
          },
          "success": {
            "type": "boolean"
          },
          "entityCount": {
            "type": "integer",
            "format": "int32"
          },
          "version": {
            "type": "string",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One recent watchlist-refresh attempt (success or failure), newest first. Failure rows\r\n            carry the error; they are pruned after a 7-day retention window."
      },
      "WatchlistSourceHealth": {
        "type": "object",
        "properties": {
          "sourceList": {
            "type": "string",
            "nullable": true
          },
          "isSanctionsSource": {
            "type": "boolean"
          },
          "lastSuccessAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "successAgeHours": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "consecutiveFailures": {
            "type": "integer",
            "format": "int32"
          },
          "lastError": {
            "type": "string",
            "nullable": true
          },
          "isStale": {
            "type": "boolean"
          },
          "isFailing": {
            "type": "boolean"
          },
          "severity": {
            "$ref": "#/components/schemas/WatchlistHealthSeverity"
          },
          "lastEntityCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "isUnhealthy": {
            "type": "boolean",
            "description": "Stale OR failing — i.e. not fully healthy.",
            "readOnly": true
          }
        },
        "additionalProperties": false,
        "description": "The health of ONE shared-corpus watchlist source: when it last succeeded, how stale that is, how many\r\nconsecutive failures have piled up since, the last error, and the computed status/severity."
      },
      "WatchlistSourceStat": {
        "type": "object",
        "properties": {
          "sourceList": {
            "type": "string",
            "nullable": true
          },
          "entityCount": {
            "type": "integer",
            "format": "int32"
          },
          "version": {
            "type": "string",
            "nullable": true
          },
          "downloadedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "versionEntityCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One ingested source list: how many entities are currently indexed for it and the\r\nversion metadata recorded at ingestion time."
      },
      "WatchlistStats": {
        "type": "object",
        "properties": {
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WatchlistSourceStat"
            },
            "nullable": true
          },
          "totalEntities": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Per-source watchlist counts plus the ingested total."
      },
      "WebhookCaptureBinDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "tokenPrefix": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "rotatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "expiresAfterHours": {
            "type": "integer",
            "format": "int32"
          },
          "maxCaptures": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "A capture bin as listed back to the tenant. Never carries the token."
      },
      "WebhookCaptureDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The capture's id.",
            "format": "uuid"
          },
          "receivedAt": {
            "type": "string",
            "description": "When it arrived.",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "description": "When it will be purged.",
            "format": "date-time"
          },
          "method": {
            "type": "string",
            "description": "The HTTP method used.",
            "nullable": true
          },
          "contentType": {
            "type": "string",
            "description": "The declared content type.",
            "nullable": true
          },
          "eventType": {
            "type": "string",
            "description": "The `X-AML-Event` header value, if any.",
            "nullable": true
          },
          "eventId": {
            "type": "string",
            "description": "The `X-AML-Event-Id` header value, if any.",
            "nullable": true
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "The retained request headers. UNTRUSTED, sender-chosen names and values — render as inert text.",
            "nullable": true
          },
          "body": {
            "type": "string",
            "description": "The request body, truncated at the size cap. UNTRUSTED text: never render as markup, never\r\nevaluate, never inject into a DOM as HTML.",
            "nullable": true
          },
          "bodyTruncated": {
            "type": "boolean",
            "description": "True when only a prefix of the body is stored."
          },
          "bodyByteCount": {
            "type": "integer",
            "description": "The body's true byte length before truncation.",
            "format": "int32"
          },
          "signatureStatus": {
            "type": "string",
            "description": "One of `verified`, `mismatch`, `missing`, `unverifiable` — deliberately four\r\nstates, so a signing bug is never reported as a generic failure.",
            "nullable": true
          },
          "signatureHeader": {
            "type": "string",
            "description": "The signature the sender presented, echoed for diffing.",
            "nullable": true
          },
          "expectedSignature": {
            "type": "string",
            "description": "What we computed for this payload. Present ONLY on a mismatch — that comparison is the reason\r\nthis tool exists.",
            "nullable": true
          },
          "verifiedWithEndpointId": {
            "type": "string",
            "description": "Which endpoint's secret verified it, when one did.",
            "format": "uuid",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One captured webhook POST as returned to the tenant."
      },
      "WebhookDeliveryDto": {
        "type": "object",
        "properties": {
          "eventType": {
            "type": "string",
            "description": "The event that was delivered, e.g. `screening.completed`.",
            "nullable": true
          },
          "url": {
            "type": "string",
            "description": "The endpoint URL this attempt targeted.",
            "nullable": true
          },
          "success": {
            "type": "boolean",
            "description": "True when the receiver returned a 2xx."
          },
          "statusCode": {
            "type": "integer",
            "description": "The HTTP status the receiver returned, or null on a network error/timeout.",
            "format": "int32",
            "nullable": true
          },
          "error": {
            "type": "string",
            "description": "Our reason for a failure with no usable HTTP response (network, timeout, signing).",
            "nullable": true
          },
          "responseBody": {
            "type": "string",
            "description": "A bounded prefix of what the RECEIVER wrote back — usually the only place the actual cause of a 4xx\r\nappears. UNTRUSTED, receiver-controlled text: render as inert text only, never as markup.",
            "nullable": true
          },
          "attemptNumber": {
            "type": "integer",
            "description": "Which attempt this was for its event (starts at 1).",
            "format": "int32"
          },
          "nextAttemptAt": {
            "type": "string",
            "description": "When it will be retried, or null when no further attempt will be made.",
            "format": "date-time",
            "nullable": true
          },
          "outboxStatus": {
            "type": "string",
            "description": "The event's state after this attempt: `delivered`, `failed` (retry pending) or\r\n`dead_lettered`. Null for synchronous test sends, which have no retry lifecycle.",
            "nullable": true
          },
          "deadLettered": {
            "type": "boolean",
            "description": "True when the retry budget was exhausted and the event was permanently abandoned — the state that\r\nneeds human attention, surfaced here rather than only in an in-cluster log."
          },
          "attemptedAt": {
            "type": "string",
            "description": "When this attempt was made.",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "A webhook delivery attempt as shown to the tenant."
      },
      "WebhookEndpointDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "nullable": true
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "active": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "A webhook endpoint as listed back to a caller (never includes the signing secret)."
      },
      "WebhookTestResultDto": {
        "type": "object",
        "properties": {
          "endpointId": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "nullable": true
          },
          "eventId": {
            "type": "string",
            "format": "uuid"
          },
          "success": {
            "type": "boolean"
          },
          "statusCode": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "responseBody": {
            "type": "string",
            "description": "A bounded prefix of what the receiver wrote back. The point of the test endpoint is to answer \"why\r\ndid my receiver reject this?\", and that reason is usually in the body rather than the status code.\r\nUNTRUSTED, receiver-controlled text — render as inert text only.",
            "nullable": true
          },
          "attemptedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "The result of a test delivery, as returned to the tenant."
      },
      "WithdrawConsentResponse": {
        "type": "object",
        "properties": {
          "subjectReference": {
            "type": "string",
            "nullable": true
          },
          "recordsWithdrawn": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "description": "Tenant API key for machine-to-machine calls. Paste the key you were issued (it begins with `aml_`). It is sent as a request header and is never stored in this document.",
        "name": "X-Api-Key",
        "in": "header"
      },
      "OpenIdConnect": {
        "type": "oauth2",
        "description": "Interactive sign-in via the PROOViD identity service (Authorization Code + PKCE). No client secret is used or stored.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://wl.proovid.com/connect/authorize",
            "tokenUrl": "https://wl.proovid.com/connect/token",
            "scopes": {
              "openid": "Sign in",
              "profile": "Basic profile",
              "email": "Email address",
              "roles": "Role claims used by the authorization policies"
            }
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Audit",
      "description": "The comprehensive audit log: every mutating transaction in the system is recorded and exposed\r\nhere, tenant-scoped (the tenant is taken from the authenticated principal — API key or OIDC).\r\nReading needs Screening.Read. Supports JSON paging and a regulator-ready CSV export\r\n(`?format=csv` or `Accept: text/csv`)."
    },
    {
      "name": "BatchScreening",
      "description": "Asynchronous batch screening for LARGE files (thousands of rows). A tenant uploads a CSV or XLSX\r\nof subjects; the rows are parsed and stored and a background processor screens them through the\r\nsame pipeline as the single-screen endpoint. The caller gets a 202 with a job id and polls for\r\nstatus/results. The tenant is taken from the authenticated principal, never from the request.\r\n            \r\n\n<b>This is the ONLY asynchronous screening entry point.</b> The upload returns\r\n`202 Accepted` with a job id and NO results; the rows are screened afterwards, off the request.\r\nThe other two entry points are synchronous and return their results inline —\r\n`POST /v1/screenings/check` (one subject, `201 Created`) and\r\n`POST /v1/screenings/bulk` (many subjects, `200 OK`). Do not poll those; there is nothing\r\nto poll."
    },
    {
      "name": "Branding",
      "description": "White-label branding: a tenant reads its effective branding (used to brand embedding apps and the\r\nbundled UIs); an admin sets it. The API itself stays brand-neutral — this is opt-in per tenant."
    },
    {
      "name": "BulkScreening",
      "description": "Bulk search (PowerPoint slide 17): screen many subjects in one request. Accepts either a JSON\r\narray of subjects or a CSV upload (multipart/form-data). Each row is screened through the same\r\npipeline as the single-screen endpoint, so each row counts as one API screen against the tenant's\r\nquota. Rows are isolated — a row that fails yields an error entry while the rest still process.\r\nThe tenant is taken from the authenticated principal, never from the request.\r\n            \r\n\n<b>SYNCHRONOUS.</b> Every row is screened inline and the `200 OK` body carries all of\r\ntheir finished results. No job id, nothing to poll, no partial state — the response either holds\r\nthe whole run or the call failed. Response time therefore scales with the number of rows, so size\r\nthe request against your client timeout; for large files use the asynchronous\r\n`POST /v1/screenings/batch` instead, which is the only screening entry point that returns\r\n`202 Accepted` and a job id."
    },
    {
      "name": "Cases",
      "description": "Case-management back-office: list/filter screenings, view full detail, set a reviewer\r\ndisposition, and add case notes. Tenant-scoped (the tenant is taken from the authenticated\r\nprincipal — API key or OIDC). Reading needs Screening.Read; disposition/notes need Screening.Write."
    },
    {
      "name": "CountryCoverage",
      "description": "The published per-country × per-office PEP coverage grid (design §3.4): for every registry country, the\r\noffice cells (green/amber/red/known-gap) and a rollup, stamped with the registry version measured\r\nagainst. Tenant-agnostic transparency data carrying no tenant data, served anonymously like the sibling\r\n`GET /v1/pep-coverage` matrix. Served instantly from the cache the coverage-audit job keeps warm;\r\nbefore the first run it returns the registry structure with zero counts."
    },
    {
      "name": "Coverage",
      "description": "A tenant's self-serve screening-coverage config: list the ready-made presets and apply one as the\r\ntenant's global default (which lists are screened + which PEP levels count + the decision policy),\r\nor reset to the full-scope default. Tenant-scoped — the tenant is taken from the authenticated\r\nprincipal (OIDC bearer or API key), never from the route. Per-screen overrides use the\r\n`coveragePreset` field on the screening request instead."
    },
    {
      "name": "DeceasedConfig",
      "description": "The per-tenant deceased-determination configuration surface (COV-8 + COV-12). A tenant READS its own\r\nactive config — the COV-8 hide switch plus the three additive COV-12 determination methods\r\n(`death_date` recorded, `age_over_max` presumed, `service_over_max` presumed) and their\r\nthresholds — and a tenant ADMIN updates it. The config drives how deceased matches (dead PEPs /\r\nadverse-media) are hidden; a deceased SANCTIONS or CRIMINAL match is never hidden regardless. This is\r\nalso the data the screening page renders its \"active determination methods + thresholds\" step from\r\n(also echoed on every screening response as `tenantDeceasedConfig`)."
    },
    {
      "name": "DecisionMatrix",
      "description": "The explicit per-tenant screening decision matrix (#223): the (category × evidence-tier × single/multi)\r\ngrid the Risk Scoring Engine resolves each match's base decision from."
    },
    {
      "name": "Demo",
      "description": "Browser-facing configuration for the shared public demo tenant.\r\n            \r\nExists so the public playground / docs pages can obtain the demo API key at RUNTIME from\r\nconfiguration instead of carrying it hard-coded in served JavaScript. The key still reaches the\r\nbrowser either way — it is public by construction — but sourcing it from config means it can be\r\nrotated with a single env change, and no credential is committed to a tracked file. (The\r\npreviously hard-coded key was revoked, which silently 401'd the playground and the whole API test\r\nsuite; nothing surfaced it because the credential lived in code.)"
    },
    {
      "name": "ExternalProviders",
      "description": "Admin management of a tenant's external (commercial) screening providers — the per-tenant\r\nopt-in that augments the local engine \"over and above\". The tenant's API key is write-only\r\n(encrypted at rest, never returned). Admin-only (OIDC)."
    },
    {
      "name": "Ingest",
      "description": "Watchlist ingest history — the data provenance + recency timeline over the refresh audit trail.\r\nRead-only, platform-level (the watchlists are shared across tenants), gated on Screening.Read.\r\nOn-demand refresh + live job status live on AMLService.API.Controllers.IngestJobController."
    },
    {
      "name": "IngestJob",
      "description": "The on-demand ingest job: live status (running / idle + last outcome) and a re-ingest trigger. A full\r\ningest is ~50 minutes, so the trigger is async — it queues a run, returns 202, and a background runner\r\non some pod executes it. Status reads need Screening.Read; triggering needs Platform.Operations."
    },
    {
      "name": "Jobs",
      "description": "The unified live job-status feed: reports every background job (the watchlist ingest, the coverage\r\nself-audit, the offline re-tag) with its state, current phase and a live progress measure, read from\r\nthe shared AMLService.Application.Jobs.JobStatusRegistry. Polled by the admin \"Jobs\" console page. Requires\r\nScreening.Read. Starting a job on demand lives on AMLService.API.Controllers.JobTriggersController."
    },
    {
      "name": "JobTriggers",
      "description": "On-demand job triggering: which jobs can be started by hand, the provenance of their recent runs, and\r\nthe trigger itself. Kept separate from AMLService.API.Controllers.JobsController (the live status feed) because the\r\ntwo answer different questions for different callers — reading progress needs Screening.Read, while\r\nstarting a deployment-wide job needs Admin."
    },
    {
      "name": "Leaders",
      "description": "The transparent, filterable leaders catalog: exactly which head-of-state / head-of-government\r\nholders (and, optionally, their relatives) we hold, country by country, with the dates each person\r\nheld office and a link back to the Wikidata source for every row. Read-only reference data — the\r\nsame for every tenant — but still gated on a tenant credential (OIDC bearer or API key) with\r\nScreening.Read, like the other data endpoints. See `/docs/api-reference.html` for the field\r\nand pepClass semantics (including the customer-relative Domestic/Foreign caveat)."
    },
    {
      "name": "MatchingProfiles",
      "description": "Admin management of a tenant's named matching profiles: list (with the system presets), create,\r\nupdate, delete, switch the active one, and reset to a preset. The active profile's parameters are\r\nwritten through to the tenant's risk profile, which the matcher reads. Admin-only (OIDC)."
    },
    {
      "name": "Me",
      "description": "The calling identity's own context — tenant id + name (and email when signed in via OIDC) —\r\nso the bundled UIs can show \"you're acting for <tenant>\" without exposing the tenant\r\ndirectory. Tenant-scoped (API key or OIDC token); returns only the caller's own tenant."
    },
    {
      "name": "MonitoringConfig",
      "description": "A tenant's self-serve ongoing-monitoring config: read and toggle whether the tenant participates in\r\nthe monitoring sweeps, plus an optional per-tenant daily-cadence override. Tenant-scoped — the\r\ntenant is taken from the authenticated principal (OIDC bearer or API key), never from the route."
    },
    {
      "name": "Monitoring",
      "description": "A tenant's ongoing-monitoring registry. Subjects are enrolled via `monitor:true` on a\r\nscreen; these endpoints let the tenant list and stop monitoring. Tenant-scoped — the tenant is\r\ntaken from the authenticated principal (OIDC bearer or API key), never from the route."
    },
    {
      "name": "PepCoverage",
      "description": "The published, self-audited PEP data-coverage matrix: every FATF category, its tier, and the live\r\nmeasured available-vs-ingested counts, including any self-detected gaps (current holders reachable\r\nbut not ingested — the signal that would have flagged the Cyprus speaker). Distinct from the tenant\r\nscreening-coverage <em>presets</em> at `/v1/coverage`: this describes what the platform's PEP\r\ndata includes, not what a tenant chooses to screen against. Read-only reference data, the same for\r\nevery tenant, gated on Screening.Read. Refreshed at most daily."
    },
    {
      "name": "Peps",
      "description": "The full, paginated, filterable PEP catalog: every politically-exposed person we hold (~188k\r\nWikidata entities), filterable by name, country and office category, with the office categories,\r\nderived PEP tier and jurisdiction per row and a link back to the Wikidata source. Read-only\r\nreference data — the same set for every tenant — but gated on a tenant credential (OIDC bearer or\r\nAPI key) with Screening.Read, like the leaders catalog. The Domestic/Foreign tier split is graded\r\nagainst the calling tenant's home jurisdiction. CSV / PDF exports flatten the same filtered set."
    },
    {
      "name": "Privacy",
      "description": "Data-privacy / GDPR back-office: data-subject-rights operations (export / erase / restrict /\r\nobject / rectify) and consent capture, all keyed by the consumer's stable userReference and\r\ntenant-scoped (the tenant is taken from the authenticated principal — API key or OIDC). Reads use\r\nScreening.Read; mutating operations use Screening.Write (which includes the admin role), mirroring\r\nthe case-management back-office convention."
    },
    {
      "name": "Quota",
      "description": "Screening-quota management: an admin sets a tenant's monthly cap; a tenant can read its own\r\ncurrent-month usage (via its API key or an OIDC token)."
    },
    {
      "name": "Register",
      "description": "Public self-service registration — anyone can provision a SANDBOX trial tenant and start testing,\r\nno admin needed. This is the one unauthenticated door into an expensive, disk-bound screening\r\nengine, so it is deliberately fenced:\r\n            \r\n<list type=\"bullet\"><item>it mints a non-billable `aml_test_` key — <b>never</b> a production `aml_live_` one,\r\n      so a stranger cannot obtain a credential indistinguishable from a paying customer's;</item><item>the trial tenant gets a small sandbox screening quota, bounding what an unverified caller can\r\n      cost us;</item><item>it is rate-limited per IP <b>and</b> globally (a per-IP cap alone is blind to a distributed\r\n      flood, where N addresses mint N tenants each with its own quota).</item></list>\r\n            \r\nUpgrading to a live key + a real quota is an admin action (`POST /v1/tenants/{id}/api-keys`),\r\ni.e. it takes a human — which is the verification gate until e-mail verification lands."
    },
    {
      "name": "RiskProfiles",
      "description": "Admin management of a tenant's risk profile: the category / country weight maps, banding\r\nthresholds, enabled lists, fuzzy threshold, and decision-policy flags consumed by the Risk\r\nScoring Engine. Admin-only (OIDC)."
    },
    {
      "name": "Screening",
      "description": "The screening core. Accepts either an OIDC bearer token or an API key; the tenant is\r\nalways taken from the authenticated principal, never from the request body.\r\n            \r\n\n<b>Three entry points, and they do not behave alike.</b>`POST /v1/screenings/check` screens ONE subject SYNCHRONOUSLY and returns `201 Created`\r\nwith the finished result in the body.\r\n`POST /v1/screenings/bulk` screens MANY subjects SYNCHRONOUSLY and returns `200 OK` with\r\nevery row's result inline — one request, one response, no job.\r\n`POST /v1/screenings/batch` is the only ASYNCHRONOUS one: it returns `202 Accepted` with a\r\njob id, screens the rows in the background, and the caller polls\r\n`GET /v1/screenings/batch/{jobId}` for status and\r\n`GET /v1/screenings/batch/{jobId}/results` for the rows.\r\nChoose `batch` only for large files; `check` and `bulk` never return a job id and\r\nthere is nothing to poll for."
    },
    {
      "name": "ScreeningSearch",
      "description": "Ranked Postgres full-text search across the tenant's screening + case history. Accepts either an\r\nOIDC bearer token or an API key; the tenant is always taken from the authenticated principal.\r\nReading needs Screening.Read."
    },
    {
      "name": "Stats",
      "description": "Platform-wide statistics for operators. Admin-only; aggregates watchlist, screening and\r\ntenant counts across every tenant. Backs the bundled dashboard at `/stats/index.html`."
    },
    {
      "name": "Subjects",
      "description": "The tenant's subject registry. Register a person once, then screen them with\r\n`{\"subjectId\": \"...\"}` instead of re-sending identity details on every call — which is how\r\nthose details drift between screens today. Entirely optional: the inline\r\n`POST /v1/screenings/check` path is unchanged and remains fully supported."
    },
    {
      "name": "Tenants",
      "description": "Tenant onboarding + API-key management. Admin-only (OIDC). The wizard and PROOViD's\r\nservice account both call POST /v1/tenants — the single onboarding call."
    },
    {
      "name": "ThresholdConfig",
      "description": "Turnover-threshold config: an admin sets a tenant's threshold amount + currency + window (the\r\nopt-in switch — a null threshold clears it and the engine goes inert); a tenant reads its own\r\nconfig (via its API key or an OIDC token). Setting the threshold is the ONLY thing that turns\r\nthe feature on, so it stays inert until an admin opts a tenant in."
    },
    {
      "name": "Threshold",
      "description": "Opt-in turnover-threshold monitoring. A consumer reports turnover events for a subject; the\r\nengine maintains a rolling-window sum per subject and, when the tenant's configured threshold is\r\ncrossed, auto-triggers an enhanced re-screen. Tenant-scoped — the tenant is taken from the\r\nauthenticated principal (OIDC bearer or API key), never from the request body."
    },
    {
      "name": "Ui",
      "description": "Browser-facing configuration for the bundled static UI.\r\n            \r\nExists so the bundled JS carries NO deployment-specific host OR mode hard-coded in served\r\nJavaScript. Every value is sourced at RUNTIME from configuration, following the same pattern as\r\n`GET /v1/demo/config`: ONE codebase then serves both our commercial SaaS and a self-hosted\r\nclient appliance correctly without editing the JS, and the distribution neutralise step has nothing\r\nto rewrite."
    },
    {
      "name": "WatchlistHealth",
      "description": "Per-source health of the SHARED watchlist corpus: for each source list, when it last refreshed\r\nsuccessfully, how stale that is, its consecutive-failure count, last error, and a computed\r\nstale/failing status + severity. The corpus is shared across every tenant, so one source silently\r\nfailing degrades screening for all of them — this endpoint makes that queryable (for the console and\r\nops), alongside the scheduled log alert that carries the same summary into the daily report.\r\nRead-only, platform-level, gated on Screening.Read (mirrors AMLService.API.Controllers.IngestController)."
    },
    {
      "name": "WatchlistsAdmin",
      "description": "Administrative operations over the ingested watchlists. Separate from the screening surface so each\r\ncontroller carries a single responsibility."
    },
    {
      "name": "WebhookCapture",
      "description": "The hosted webhook receiver (\"capture bin\") — a URL we host that ACCEPTS webhook POSTs and shows\r\nthe tenant what arrived, so an integration can be proven end-to-end before the tenant has a\r\npublic receiver of their own."
    },
    {
      "name": "Webhooks",
      "description": "A tenant's self-serve webhook management: create endpoints (signing secret shown once), list them,\r\ndelete them, and view delivery history. Tenant-scoped — the tenant is taken from the authenticated\r\nprincipal (OIDC bearer or API key), never from the route.\r\n            \r\n\n<b>Webhooks are not how you get a screening result.</b>`POST /v1/screenings/check` is\r\nsynchronous: its `201` body already carries the finished, final result. The\r\n`screening.completed` event is a MIRROR of that same response, projected from the same object\r\nthrough one shared factory so the two cannot disagree, and it is queued to a durable outbox and\r\ndelivered off the request path — so it is never a prerequisite of the `201` and carries nothing\r\nthe `201` did not already say. Use webhooks for state you did NOT ask for, chiefly\r\n`monitoring.alert`.\n<b>Event types.</b>`screening.completed` (the default subscription) — a screen finished\r\nvia `POST /v1/screenings/check` or `POST /v1/screenings/{id}/rescreen`; bulk and batch rows\r\ndo NOT raise it. `monitoring.alert` — an enrolled subject's outcome CHANGED on a watchlist\r\nupdate, which is the one genuinely unsolicited screening result. `threshold.breached` — a\r\nturnover threshold was crossed.\n<b>De-duplicate on the event id (`X-AML-Event-Id`), not on the screening id.</b> An\r\nidempotency REPLAY of `POST /v1/screenings/check` re-emits `screening.completed` carrying\r\nthe ORIGINAL `screeningId`, so the same screening id can legitimately arrive more than once;\r\n`POST /v1/screenings/{id}/rescreen` emits the same event type with a NEW `screeningId`.\r\nThe event type alone therefore tells a receiver nothing about which of the two occurred.\n<b>Payloads are PII-light and category-only.</b> Screening-derived events carry the caller's\r\nown `userReference` plus a summary — `classification`, `pepTiers`, `sourceLists`,\r\n`matchCount`, `adverseMediaStatus` — and never the subject's or any matched entity's name.\r\n`pepTiers` is an unordered SET, not a ranking: the engine has no severity order across tiers, so\r\nnaming one of them \"the\" tier would invent one. `matchCount` counts VISIBLE matches only —\r\ndeceased-suppressed matches are excluded from it, as they were from the decision, and appear only on\r\nthe synchronous response as `suppressedMatches` / `suppressedDeceasedCount`. And\r\n`adverseMediaStatus: Unavailable` means the source could NOT be checked — not that the subject\r\nis clean."
    }
  ]
}