# API Keys API
Source: https://docs.coverbase.com/api-reference/api-keys
Manage your organization's ak_* public-API keys: list, create, rotate, revoke, and grant admin scopes.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The API Keys API lets an organization administrator manage the `ak_*` keys used to authenticate the Coverbase public API without contacting Coverbase support.
These endpoints accept **either** an admin dashboard session JWT (a user with the `admin` org role) **or** an `ak_*` key that carries the `keys:manage` [scope](#key-scopes). The scoped-key path lets headless and middleware integrations manage keys without a short-lived dashboard token. A standard integration key carries no scopes and cannot manage keys, so a compromised integration key cannot be used to mint, rotate, or revoke other keys.
All operations are org-scoped to the caller's organization and recorded in the activity log as `target_type=api_key`. The Coverbase backend brokers calls to the underlying identity provider (Clerk), so customers do not need direct Clerk dashboard access. Coverbase stores only the `(org, clerk_key_id) → scopes` mapping, never the secret.
## Key scopes
A key can carry zero or more **admin scopes**. A standard integration key has none and can only call ordinary `/v1/*` routes; granting a scope turns a key into a long-lived admin credential.
| Scope | Grants |
| - | - |
| `keys:manage` | List, create, rotate, and revoke `ak_*` keys (the endpoints on this page). |
| `audit:read` | Read the org system audit log (`GET /v1/system_audit_log` and `GET /v1/system_audit_log/metadata`). |
| `banking:read` | Read full supplier bank account and tax identifiers instead of the masked last four characters. |
| `review:sensitive_changes` | Write bank details without waiting for review. It does not let a key approve or reject a change someone else queued. |
The dashboard's **API keys** page (**Configuration**, under **Developers and integrations**) offers the same scopes under **Admin scopes (optional)** when an admin creates a key. See [API key scopes](/conventions#api-key-scopes) before granting the last two.
Granting scopes is a deliberate **admin** action and requires an admin dashboard JWT. A scoped `ak_*` key **cannot** grant scopes (not to itself and not to any other key), so a leaked key can never escalate its own access. A non-admin or scoped-key caller that supplies `scopes` is rejected with `403 scope_grant_forbidden`, and a call made with a key that lacks the required scope returns `403 insufficient_scope`.
## List API keys
`GET /v1/api-keys`
Returns every `ak_*` API key belonging to your org, including revoked and expired keys. Use this to audit which keys exist before rotating or revoking.
**Auth:** admin dashboard JWT or an `ak_*` key with the `keys:manage` scope.
### Example request
```bash cURL theme={null}
# Admin JWT...
curl -X GET "https://api.coverbase.app/v1/api-keys" \
-H "Authorization: Bearer "
# ...or a key with the keys:manage scope (headless):
curl -X GET "https://api.coverbase.app/v1/api-keys" \
-H "Authorization: Bearer ak_live_xxx"
```
### Example response
```json theme={null}
{
"data": [
{
"id": "ak_2YkL...redacted",
"name": "GRC pipeline (Acme)",
"created_at": 1735689600,
"last_used_at": 1746579000,
"revoked": false,
"expired": false,
"scopes": [],
"created_by_clerk_user_id": "user_2Zx9..."
},
{
"id": "ak_7QpR...redacted",
"name": "Headless admin (middleware)",
"created_at": 1746000000,
"last_used_at": 1746579500,
"revoked": false,
"expired": false,
"scopes": ["keys:manage", "audit:read"],
"created_by_clerk_user_id": "user_2Zx9..."
}
]
}
```
### Response fields
Each entry contains:
The key's Clerk-side identifier (the prefix portion of `ak_*`). The raw secret is **not** returned by this endpoint; it is only available at the moment of creation or rotation.
Human-readable name set at creation time.
Unix timestamp (seconds) when the key was created.
Unix timestamp (seconds) of the most recent successful authentication, or `null` if never used.
`true` if the key has been revoked.
`true` if the key has passed its expiration.
The admin scopes granted to the key. Each value is one of `"keys:manage"`, `"audit:read"`, `"banking:read"`, or `"review:sensitive_changes"`. A standard integration key returns an empty array (`[]`).
The Clerk user ID of the admin who created the key.
## Create an API key
`POST /v1/api-keys`
Creates a new API key scoped to your org. The raw `ak_*` secret is returned **once** in the response body; store it immediately. Coverbase does not retain the plaintext, so a lost secret can only be replaced (rotated), not recovered.
**Auth:** admin dashboard JWT or an `ak_*` key with the `keys:manage` scope. Note that **supplying `scopes` requires an admin JWT** (see below).
### Request body
Human-readable name for the key (for example, `"ServiceNow exporter"`). Must be non-empty after trimming.
Optional. Seconds until the key automatically expires. Omit for a non-expiring key. Recommended for keys used by short-lived integrations (for example, `31536000` for a one-year rotation policy).
Optional. Admin scopes to grant the new key: any subset of `"keys:manage"`, `"audit:read"`, `"banking:read"`, and `"review:sensitive_changes"`. Omit or pass `[]` to mint a standard integration key with no elevated access. **Granting scopes requires an admin dashboard JWT**; a non-admin or scoped-key caller that supplies a non-empty `scopes` array is rejected with `403 scope_grant_forbidden`.
### Example request
```bash cURL theme={null}
# Standard integration key (no scopes), JWT or keys:manage key:
curl -X POST "https://api.coverbase.app/v1/api-keys" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{"name": "GRC pipeline (Acme)", "seconds_until_expiration": 31536000}'
# Scoped admin key - requires an admin JWT:
curl -X POST "https://api.coverbase.app/v1/api-keys" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{"name": "Headless admin (middleware)", "scopes": ["keys:manage", "audit:read"]}'
```
### Example response
`201 Created`:
```json theme={null}
{
"id": "ak_2YkL...redacted",
"name": "GRC pipeline (Acme)",
"secret": "ak_live_2YkLm3pQrStUvWxYzABCDEFGHIJKLMNOPQRSTUVWXYZabcdef",
"created_at": 1746576000,
"scopes": []
}
```
`secret` is the only place you will ever see the full token. If you lose it, rotate the key (which mints a new secret and revokes the old one). Treat the secret like a password.
## Rotate an API key
`POST /v1/api-keys/{api_key_id}/rotate`
Atomically rotates a key: mints a new key, then revokes the original. The new key keeps the original name with a `(rotated YYYY-MM-DD)` suffix, because the identity provider rejects duplicate names; a second rotation on the same day adds a counter, such as `(rotated 2025-05-07 2)`. Use this when a secret may have been compromised, or as part of a scheduled rotation policy. **The new key inherits the same scopes as the rotated key**, so a scoped admin key stays scoped after rotation.
If revocation of the original key fails after the new key is minted, the new key is automatically rolled back (also revoked) so the operation never leaves you with two simultaneously-active keys.
**Auth:** admin dashboard JWT or an `ak_*` key with the `keys:manage` scope.
### Path parameters
The key's Clerk-side identifier (the prefix portion of `ak_*`, as returned by [List API keys](#list-api-keys)).
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/api-keys/ak_2YkL.../rotate" \
-H "Authorization: Bearer "
```
### Example response
```json theme={null}
{
"id": "ak_5ZmN...newkey",
"name": "GRC pipeline (Acme) (rotated 2025-05-07)",
"secret": "ak_live_5ZmN3pQrStUvWxYzABCDEFGHIJKLMNOPQRSTUVWXYZabcdef",
"revoked_id": "ak_2YkL...redacted",
"created_at": 1746580000,
"scopes": []
}
```
Distribute the new `secret` to all systems that use the rotated key **before** removing the old one's grace period. The old key is revoked immediately on a successful rotate, so any process still using it will start receiving `401 Unauthorized` responses.
## Revoke an API key
`POST /v1/api-keys/{api_key_id}/revoke`
Revokes a key. Future requests using the revoked secret are rejected with `401 Unauthorized`. The key still appears in [List API keys](#list-api-keys) with `revoked: true` for audit purposes. **Revoking clears any scopes** the key carried, so a revoked admin key retains no elevated access.
The endpoint is **idempotent**: the first revocation (the active → revoked transition) is recorded in the activity log, but re-revoking an already-revoked key is a no-op that writes **no** additional audit entry.
**Auth:** admin dashboard JWT or an `ak_*` key with the `keys:manage` scope.
### Path parameters
The key's Clerk-side identifier.
### Request body
Optional. Free-form revocation reason (for example, `"Employee offboarded"`, `"Suspected leak in Sentry log"`). Recorded for compliance.
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/api-keys/ak_2YkL.../revoke" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{"reason": "Employee offboarded"}'
```
### Example response
`200 OK`: returns the same shape as [List API keys](#list-api-keys), with `revoked: true`.
## Authorization & audit
* Each endpoint accepts **either** an admin dashboard JWT (org **`admin` role**) **or** an `ak_*` key carrying the `keys:manage` scope. A JWT caller without the admin role, or a key without `keys:manage`, is rejected.
* **Granting scopes is admin-only.** A non-empty `scopes` array on create can only be supplied with an admin JWT; a scoped-key caller that passes `scopes` is rejected with `403 scope_grant_forbidden`. A scoped key can manage keys but can never grant scopes; there is no self-propagation.
* Create and rotate always write a `CbActivity` row (`record_creation` for create, `field_update` for rotate) against `target_type=api_key`. A revoke writes a `field_update` row **only when it transitions a key from active to revoked**; re-revoking an already-revoked key is an idempotent no-op and writes nothing. These rows are visible to admins in **Configuration → Audit Logs** (in the **Integrations** group).
## Error responses
| Status | Body | When |
| - | - | - |
| 400 | `{"detail": {"code": "invalid_name", "message": "Name cannot be empty."}}` | `name` is empty or whitespace-only on create. |
| 401 | `{"detail": "Unauthorized role."}` | A JWT whose role is not `admin`. An unknown or revoked key returns `{"detail": "Invalid or expired API key."}`. |
| 403 | `{"detail": "Not authenticated"}` | No `Authorization` header. |
| 403 | `{"detail": {"code": "insufficient_scope", "message": "..."}}` | The `ak_*` key is valid but lacks the `keys:manage` scope required for this endpoint. |
| 403 | `{"detail": {"code": "scope_grant_forbidden", "message": "..."}}` | A non-admin or scoped-key caller tried to grant `scopes` on create. Scopes can only be granted from an admin dashboard session. |
| 403 | `{"detail": {"code": "user_not_provisioned", "message": "..."}}` | The admin user record has no Clerk identity (rare; re-provision via support). |
| 404 | `{"detail": {"code": "api_key_not_found", "message": "API key not found."}}` | The `api_key_id` does not belong to your org or no longer exists. |
| 502 | `{"detail": {"code": "clerk_upstream_error", "message": "..."}}` | The upstream identity provider returned an error. Retry; contact support if it persists. |
| 502 | `{"detail": {"code": "clerk_missing_secret", "message": "..."}}` | On create/rotate, the identity provider returned an incomplete key (missing `id`/`secret`). The partial key is automatically revoked so none is left stranded, safe to retry. |
# Assessments API
Source: https://docs.coverbase.com/api-reference/assessments
Create and retrieve assessments for vendors.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Assessments API lets external systems start an assessment for an existing vendor and retrieve its state. The most common use case is a GRC tool or scheduled job kicking off a reassessment of a known vendor.
All endpoints are org-scoped to the API key. See [API conventions](/conventions) for authentication, IDs, timestamps, idempotency, and the error envelope.
## Create an assessment
`POST /v1/assessments`
Creates a new assessment for a vendor. Returns `201 Created`.
### Request body
The vendor ID (`cbvndr_...`) the assessment runs against.
Control set IDs (`cbctst_...`) to evaluate the vendor against. May be an empty array, but the field itself is required.
Assessment name. Optional.
Optional template used to auto-generate the assessment name.
Optional service IDs (`cbsvc_...`) the assessment covers.
Optional user ID (`cbuser_...`) to assign the assessment to.
Optional name of a workflow to invoke alongside the assessment. If the named workflow does not exist for the org, the request fails with `404 workflow_not_found`.
Optional document IDs (`cbvdoc_...`) to attach as supporting evidence. Upload
documents first with the [Documents API](/api-reference/documents) to obtain
these IDs.
### Headers
`Bearer ak_...`
Optional. If the same key is sent again within 24 hours for this endpoint, the original response is returned and no new assessment is created. See [Idempotency](/conventions#idempotency).
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/assessments" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Idempotency-Key: grc-reassess-2026-q2-acme" \
-H "Content-Type: application/json" \
-d '{
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"control_set_ids": ["cbctst_9f4a1c0d7b2e4e9f8c1d2b3a4e5f6071"],
"name": "Acme Q2 2026 Reassessment",
"service_ids": ["cbsvc_3c2b1a098f7e6d5c4b3a2918374655ab"],
"trigger_workflow": "annual-reassessment-flow"
}'
```
```python Python theme={null}
import os
import requests
API_KEY = os.environ["COVERBASE_API_KEY"]
BASE_URL = "https://api.coverbase.app"
payload = {
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"control_set_ids": ["cbctst_9f4a1c0d7b2e4e9f8c1d2b3a4e5f6071"],
"name": "Acme Q2 2026 Reassessment",
"service_ids": ["cbsvc_3c2b1a098f7e6d5c4b3a2918374655ab"],
"trigger_workflow": "annual-reassessment-flow",
}
resp = requests.post(
f"{BASE_URL}/v1/assessments",
headers={
"Authorization": f"Bearer {API_KEY}",
"Idempotency-Key": "grc-reassess-2026-q2-acme",
"Content-Type": "application/json",
},
json=payload,
timeout=30,
)
resp.raise_for_status()
print(resp.json())
```
### Example response
`201 Created`:
```json theme={null}
{
"id": "cbqsrw_2d5e8f1a4b7c0d3e6f9a2b5c8d1e4f7a",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"name": "Acme Q2 2026 Reassessment",
"status": "created",
"control_set_ids": ["cbctst_9f4a1c0d7b2e4e9f8c1d2b3a4e5f6071"],
"service_ids": ["cbsvc_3c2b1a098f7e6d5c4b3a2918374655ab"],
"assignee_id": "cbuser_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"score_percent": null,
"findings_count": 0,
"initiated_at": null,
"created_at": 1746576000,
"updated_at": 1746576000,
"workflow_run_id": "cbwr_a8f2c19e3d4b5e6f7a8b9c0d1e2f3a4b"
}
```
### Response fields
The new assessment ID (`cbqsrw_...`).
The vendor the assessment runs against.
The assessment name.
Assessment status. One of: `created`, `collecting_documents`, `indexing_supporting_documents`, `analyzing_questionnaire`, `review_evals`, `complete`, `failed`, `canceled`. Newly created assessments are typically `created`.
The control sets being evaluated.
The services the assessment covers.
The assigned user (`cbuser_...`), if any.
Score as a decimal (typically 0-1), or `null` until scored.
Number of findings on the assessment. `0` on creation.
Unix timestamp (seconds) when the assessment was initiated, or `null`.
Unix timestamp (seconds) when the assessment was created.
Unix timestamp (seconds) of the last update.
The workflow run created when `trigger_workflow` was supplied, otherwise `null`.
### Error responses
| Status | Body | When |
| - | - | - |
| 400 | `{"detail": {"error": "..."}}` | The assessment could not be created (for example, an invalid `vendor_id`, `control_set_ids`, `service_ids`, or `assignee_id`). `error` contains the reason. |
| 404 | `{"detail": {"code": "workflow_not_found", "message": "Workflow '...' not found."}}` | `trigger_workflow` was supplied but no workflow with that name exists for the org. |
| 422 | Standard validation error | The request body failed schema validation (for example, `vendor_id` or `control_set_ids` missing). See [API conventions](/conventions#validation-errors). |
Re-sending a request with a previously used `Idempotency-Key` returns the **original** `201` response body. It does not return a conflict error.
## Retrieve an assessment
`GET /v1/assessments/{assessment_id}`
Fetches a single assessment by ID.
### Path parameters
The assessment ID (`cbqsrw_...`).
### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/assessments/cbqsrw_2d5e8f1a4b7c0d3e6f9a2b5c8d1e4f7a" \
-H "Authorization: Bearer ak_live_xxx"
```
### Example response
```json theme={null}
{
"id": "cbqsrw_2d5e8f1a4b7c0d3e6f9a2b5c8d1e4f7a",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"name": "Acme Q2 2026 Reassessment",
"status": "complete",
"control_set_ids": ["cbctst_9f4a1c0d7b2e4e9f8c1d2b3a4e5f6071"],
"service_ids": ["cbsvc_3c2b1a098f7e6d5c4b3a2918374655ab"],
"assignee_id": "cbuser_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"score_percent": 0.82,
"findings_count": 3,
"initiated_at": 1746576000,
"custom_fields": [
{
"config_id": "cbcfc_1d4a7b0e3f6c9a2d5b8e1f4a7c0d3e6f",
"field_name": "Review Cycle",
"field_type": "string",
"value": "Annual"
}
],
"created_at": 1746576000,
"updated_at": 1746579600
}
```
The shape matches the create response, **minus** `workflow_run_id` and **plus** `custom_fields`. `findings_count` is a computed count of findings on the assessment. `custom_fields` holds any values your organization has set on this assessment; see the [Custom Fields API](/api-reference/custom-fields).
### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "assessment_not_found", "message": "Assessment not found."}}` | The `assessment_id` does not exist or is not in the API key's org. |
## Cancel (archive) an assessment
`DELETE /v1/assessments/{assessment_id}`
Cancels an in-flight assessment or archives a completed one. Mirrors the in-product "Archive" action on the assessment page.
The operation is a **soft delete**: the assessment row plus its evals and findings are marked `is_archived=true`, the assessment's portal (if any) is closed, and any in-flight workflow runs targeting the assessment are canceled in the workflow engine on a best-effort basis. The underlying rows are retained for audit; `GET /v1/assessments/{assessment_id}` will continue to return them.
### Path parameters
The assessment ID (`cbqsrw_...`).
### Example request
```bash cURL theme={null}
curl -X DELETE "https://api.coverbase.app/v1/assessments/cbqsrw_2d5e8f1a4b7c0d3e6f9a2b5c8d1e4f7a" \
-H "Authorization: Bearer ak_live_xxx"
```
### Example response
`200 OK`:
```json theme={null}
{
"id": "cbqsrw_2d5e8f1a4b7c0d3e6f9a2b5c8d1e4f7a",
"status": "canceled",
"is_archived": true,
"archived_at": 1746580000
}
```
### Response fields
The archived assessment ID.
Assessment status at the time of archival. The workflow engine receives a best-effort cancel signal immediately after archive; transient runs may still surface a brief `canceled` lifecycle event.
Always `true` after a successful archive.
Unix timestamp (seconds) when the archive took effect.
### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "assessment_not_found", "message": "Assessment not found."}}` | The `assessment_id` does not exist or is not in the API key's org. |
Archive is idempotent: archiving an already-archived assessment returns `200` with the same envelope. To restore an archived assessment, use the Coverbase dashboard.
# Bill of Materials API
Source: https://docs.coverbase.com/api-reference/bill-of-materials
Upload, version, and search machine-readable bills of materials (SBOM, AIBOM, HBOM, SaaSBOM) for vendors and services.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A **bill of materials** (`cbbom_...`) is a machine-readable inventory of the components that make up a vendor's product or a specific service. Upload one as a document, and Coverbase parses it in the background into a searchable list of [components](#the-component-object) (`cbbomc_...`), each traceable back to the exact source file and vendor it came from.
Supported BOM kinds: **SBOM** (software), **AIBOM** (AI/ML models and datasets), **HBOM** (hardware), **SaaSBOM**, and `other`. Supported formats are **CycloneDX (JSON)** and **SPDX (JSON)**; files in any other format are still stored, but are not parsed into components.
All endpoints are org-scoped. They are the endpoints the dashboard's **Bill of Materials** tab uses, so they take a signed-in user's dashboard session token (a JWT): an `ak_` API key is rejected with `401 Unauthorized role.` See [Availability](#availability) below, and [API conventions](/conventions) for IDs, timestamps, and the error envelope.
| Method | Path | Idempotent |
| - | - | - |
| `POST` | `/v1/bill_of_materials` | No |
| `GET` | `/v1/bill_of_materials/latest` | - |
| `GET` | `/v1/bill_of_materials` | - |
| `GET` | `/v1/bill_of_materials/{bom_id}` | - |
| `GET` | `/v1/bill_of_materials/{bom_id}/components` | - |
| `GET` | `/v1/bill_of_materials/components` | - |
| `POST` | `/v1/bill_of_materials/{bom_id}/promote` | No |
| `POST` | `/v1/bill_of_materials/{bom_id}/archive` | No |
## How BOMs are versioned
A BOM is uploaded as a document and can be linked to **a vendor, a single service, multiple services, or the vendor only**, the same linking model as vendor documents.
**Many BOMs can be uploaded over time** for the same vendor or service, and the platform keeps **all of them** as history. One non-archived BOM is "applied": the one uploaded or [promoted](#promote-a-historical-bom) most recently. It is shown as current on the vendor or service page and returned by [`GET /v1/bill_of_materials/latest`](#get-the-current-applied-bom). Older BOMs remain viewable and downloadable as history via [`GET /v1/bill_of_materials`](#list-the-upload-history). [Archiving a BOM](#archive-a-bom) drops it from "latest" but keeps it in history.
### Parse lifecycle
On upload a BOM starts at `parse_status: "pending"` and is parsed asynchronously. Poll the BOM (or the `latest`/list endpoints) to watch it move through the lifecycle:
| `parse_status` | Meaning |
| - | - |
| `pending` | Registered, not yet picked up by the parser. |
| `parsing` | Parse in progress. |
| `parsed` | Parsed successfully; `components` are available. |
| `failed` | Parsing was attempted but failed (see `parse_error`). |
| `unsupported` | File format is not CycloneDX or SPDX JSON; the file is stored but not parsed. |
## The bill of materials object
Bill of materials ID (`cbbom_...`).The owning vendor (`cbvndr_...`).The stored source file (`cbvdoc_...`), downloadable via the `document` object.One of `cyclonedx`, `spdx`, or `unknown`.One of `sbom`, `aibom`, `hbom`, `saasbom`, or `other`.One of `pending`, `parsing`, `parsed`, `failed`, `unsupported`. See [parse lifecycle](#parse-lifecycle).Spec version of the source document, for example, `1.5` (CycloneDX) or `SPDX-2.3`.Document serial number, if present in the source.Number of parsed components.BOM subject / primary component name.Set when `parse_status` is `failed` or `unsupported`.Unix timestamp (seconds) when parsing completed.Free-form metadata from the source document header (tools, authors, timestamp, lifecycle). Empty until parsed.Whether the BOM has been archived.Unix timestamp (seconds) of upload.Unix timestamp (seconds) of last update.The stored source file: `{ id, name, s3_url, size, extension, created_at }`.The parsed [components](#the-component-object). Present on **detail** responses only (`/latest`, `/{bom_id}`, and the upload response); omitted from list summaries and from the promote and archive responses.
## The component object
Component ID (`cbbomc_...`).The BOM this component belongs to (`cbbom_...`).The source file the component was parsed from (`cbvdoc_...`).Component name. **Required**: the one field always present.Component version.Package URL (PURL).Common Platform Enumeration identifier.Namespace / group (for example, Maven groupId).Supplier or publisher.Author.Free-text description.The source document's internal reference for this component.One of `application`, `library`, `framework`, `container`, `operating-system`, `device`, `firmware`, `file`, `machine-learning-model`, `data`, `other`.Declared licenses.Map of hash algorithm to value (for example, `{ "SHA-256": "..." }`).External references from the source document.Arbitrary key/value properties from the source document.Unix timestamp (seconds).
## Upload a BOM
`POST /v1/bill_of_materials`
Registers a BOM against a vendor (and optionally one or more services), then parses it asynchronously. Returns the new BOM with `parse_status: "pending"`.
Upload the file first with the presigned POST from `GET /v1/file/uploadable_url?extension=json`, then pass the uploaded file's URL here.
### Request body
The owning vendor (`cbvndr_...`).
The URL of the uploaded file: the presigned `url` from `GET /v1/file/uploadable_url` followed by the `key` it returned in `fields`.
File size in bytes.
File name (for example, `acme-sbom.cdx.json`).
File extension (for example, `json`).
Optional. Link the BOM to one or more services (`cbsvc_...`) under the vendor. Omit to link the BOM to the vendor only.
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/bill_of_materials" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"s3_url": "https://coverbase-uploads.s3.amazonaws.com/7c1d9e2b41f04c5e8a3b6d0f9e2c4a71",
"size": 20480,
"name": "acme-sbom.cdx.json",
"extension": "json",
"service_ids": ["cbsvc_3c2b1a098f7e6d5c4b3a2918374655ab"]
}'
```
### Example response
`200 OK`: the new [bill of materials object](#the-bill-of-materials-object), freshly registered:
```json theme={null}
{
"id": "cbbom_9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"vendor_document_id": "cbvdoc_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
"format": "unknown",
"bom_type": "other",
"parse_status": "pending",
"spec_version": null,
"serial_number": null,
"component_count": 0,
"name": null,
"parse_error": null,
"parsed_at": null,
"bom_metadata": {},
"is_archived": false,
"created_at": 1748822400,
"updated_at": 1748822400,
"document": {
"id": "cbvdoc_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
"name": "acme-sbom.cdx.json",
"s3_url": "https://coverbase-uploads.s3.amazonaws.com/7c1d9e2b41f04c5e8a3b6d0f9e2c4a71",
"size": 20480,
"extension": "json",
"created_at": 1748822400
},
"components": []
}
```
`format`, `bom_type`, `spec_version`, and `component_count` are populated once parsing completes.
### Error responses
| Status | Body | When |
| - | - | - |
| 422 | Standard validation error | A required field is missing or the body is malformed. |
## Get the current applied BOM
`GET /v1/bill_of_materials/latest`
Returns the latest applied BOM (with its [components](#the-component-object)) for a vendor **or** a service. Returns `null` if none has been uploaded.
### Query parameters
A vendor (`cbvndr_...`). Provide **exactly one** of `vendor_id` or `service_id`.
A service (`cbsvc_...`). Provide **exactly one** of `vendor_id` or `service_id`.
Supplying both `vendor_id` and `service_id`, or neither, returns `422`.
### Example request
```bash cURL theme={null}
# The current applied BOM for a vendor (with components):
curl -X GET "https://api.coverbase.app/v1/bill_of_materials/latest?vendor_id=cbvndr_e448ba62882143f3ba0c140bb2e30162" \
-H "Authorization: Bearer "
# The current applied BOM for a specific service:
curl -X GET "https://api.coverbase.app/v1/bill_of_materials/latest?service_id=cbsvc_3c2b1a098f7e6d5c4b3a2918374655ab" \
-H "Authorization: Bearer "
```
### Example response
`200 OK`: a [bill of materials object](#the-bill-of-materials-object) with `components`, or `null`:
```json theme={null}
{
"id": "cbbom_9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"vendor_document_id": "cbvdoc_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
"format": "cyclonedx",
"bom_type": "sbom",
"parse_status": "parsed",
"spec_version": "1.5",
"serial_number": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
"component_count": 142,
"name": "acme-platform",
"parse_error": null,
"parsed_at": 1748822460,
"bom_metadata": {},
"is_archived": false,
"created_at": 1748822400,
"updated_at": 1748822460,
"document": {
"id": "cbvdoc_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
"name": "acme-sbom.cdx.json",
"s3_url": "https://coverbase-uploads.s3.amazonaws.com/7c1d9e2b41f04c5e8a3b6d0f9e2c4a71",
"size": 20480,
"extension": "json",
"created_at": 1748822400
},
"components": [
{
"id": "cbbomc_4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f",
"bill_of_materials_id": "cbbom_9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c",
"vendor_document_id": "cbvdoc_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
"name": "log4j-core",
"version": "2.17.1",
"purl": "pkg:maven/org.apache.logging.log4j/log4j-core@2.17.1",
"cpe": null,
"group": "org.apache.logging.log4j",
"supplier": "The Apache Software Foundation",
"author": null,
"description": null,
"bom_ref": "pkg:maven/org.apache.logging.log4j/log4j-core@2.17.1",
"component_type": "library",
"licenses": ["Apache-2.0"],
"hashes": { "SHA-256": "8d3e1..." },
"external_references": [],
"properties": {},
"created_at": 1748822460
}
]
}
```
## List the upload history
`GET /v1/bill_of_materials`
Returns the full upload history for a vendor or service, **newest upload first**. The first item is the currently applied BOM unless an older upload has been promoted since. Items are summaries without `components`; use [Retrieve a BOM](#retrieve-a-bom) or [List components of a BOM](#list-components-of-a-bom) to pull components.
### Query parameters
A vendor (`cbvndr_...`). Provide **exactly one** of `vendor_id` or `service_id`.
A service (`cbsvc_...`). Provide **exactly one** of `vendor_id` or `service_id`.
Include archived BOMs in the history. Defaults to `false`.
Page size. Default `25`, range `1`-`500`.
Page offset. Default `0`.
### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/bill_of_materials?vendor_id=cbvndr_e448ba62882143f3ba0c140bb2e30162&limit=25" \
-H "Authorization: Bearer "
```
### Example response
`200 OK`: a page of [bill of materials objects](#the-bill-of-materials-object) (summaries, no `components`):
```json theme={null}
{
"data": [
{
"id": "cbbom_9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"vendor_document_id": "cbvdoc_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
"format": "cyclonedx",
"bom_type": "sbom",
"parse_status": "parsed",
"spec_version": "1.5",
"serial_number": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79",
"component_count": 142,
"name": "acme-platform",
"parse_error": null,
"parsed_at": 1748822460,
"bom_metadata": {},
"is_archived": false,
"created_at": 1748822400,
"updated_at": 1748822460,
"document": { "id": "cbvdoc_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d", "name": "acme-sbom.cdx.json", "s3_url": "https://coverbase-uploads.s3.amazonaws.com/7c1d9e2b41f04c5e8a3b6d0f9e2c4a71", "size": 20480, "extension": "json", "created_at": 1748822400 }
}
],
"total_count": 3
}
```
## Retrieve a BOM
`GET /v1/bill_of_materials/{bom_id}`
Returns one BOM with its full [components](#the-component-object) list.
### Path parameters
The bill of materials ID (`cbbom_...`).
### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/bill_of_materials/cbbom_9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c" \
-H "Authorization: Bearer "
```
The response is a [bill of materials object](#the-bill-of-materials-object) with `components` populated (same shape as [the current applied BOM](#example-response-1)).
### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": "Bill of materials not found"}` | `bom_id` not found or not in your org. |
## List components of a BOM
`GET /v1/bill_of_materials/{bom_id}/components`
Returns the components of a single BOM, searchable and filterable.
### Path parameters
The bill of materials ID (`cbbom_...`).
### Query parameters
Free-text match against component fields (name, PURL, etc.).
Filter to a single `component_type` (for example, `machine-learning-model`).
Page size. Default `50`, range `1`-`200`.
Page offset. Default `0`.
### Example request
```bash cURL theme={null}
# List components of one BOM, filtered to ML models (AIBOM use case):
curl -X GET "https://api.coverbase.app/v1/bill_of_materials/cbbom_9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c/components?component_type=machine-learning-model" \
-H "Authorization: Bearer "
```
### Example response
`200 OK`: a page of [component objects](#the-component-object):
```json theme={null}
{
"data": [
{
"id": "cbbomc_4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f",
"bill_of_materials_id": "cbbom_9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c",
"vendor_document_id": "cbvdoc_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
"name": "log4j-core",
"version": "2.17.1",
"purl": "pkg:maven/org.apache.logging.log4j/log4j-core@2.17.1",
"cpe": null,
"group": "org.apache.logging.log4j",
"supplier": "The Apache Software Foundation",
"author": null,
"description": null,
"bom_ref": "pkg:maven/org.apache.logging.log4j/log4j-core@2.17.1",
"component_type": "library",
"licenses": ["Apache-2.0"],
"hashes": { "SHA-256": "8d3e1..." },
"external_references": [],
"properties": {},
"created_at": 1748822460
}
],
"total_count": 142
}
```
## Search components across a vendor
`GET /v1/bill_of_materials/components`
Search components across **all** of a vendor's BOMs at once. Because every component carries its `bill_of_materials_id` and `vendor_document_id`, each match traces straight back to the source file it came from, answering questions like "has this vendor ever shipped a BOM containing `log4j`?"
### Query parameters
The vendor to search within (`cbvndr_...`).
Free-text match against component fields.
Filter to a single `component_type`.
Restrict to a single BOM (`cbbom_...`).
Restrict to components from a single source file (`cbvdoc_...`).
Page size. Default `50`, range `1`-`200`.
Page offset. Default `0`.
### Example request
```bash cURL theme={null}
# Find every BOM across the vendor that contains a component (for example, log4j):
curl -X GET "https://api.coverbase.app/v1/bill_of_materials/components?vendor_id=cbvndr_e448ba62882143f3ba0c140bb2e30162&search=log4j" \
-H "Authorization: Bearer "
```
The response is a page of [component objects](#the-component-object) (`{ "data": [...], "total_count": }`), spanning every matching BOM for the vendor.
## Promote a historical BOM
`POST /v1/bill_of_materials/{bom_id}/promote`
Makes an older, non-archived upload the applied BOM for its vendor and for every service it is linked to, until a newer upload or another promotion replaces it. The change is recorded in the vendor's (and each linked service's) activity log.
### Path parameters
The bill of materials ID (`cbbom_...`).
The response is the promoted [bill of materials object](#the-bill-of-materials-object), without `components`. An unknown or archived `bom_id` returns `404` with `{"detail": "Bill of materials not found"}`.
## Archive a BOM
`POST /v1/bill_of_materials/{bom_id}/archive`
Archives a BOM. It drops out of "latest" (the next most recent non-archived BOM becomes the applied one) but stays in history and remains retrievable (and shows in the history list when `include_archived=true`).
### Path parameters
The bill of materials ID (`cbbom_...`).
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/bill_of_materials/cbbom_9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c/archive" \
-H "Authorization: Bearer "
```
The response is the updated [bill of materials object](#the-bill-of-materials-object) with `is_archived: true`, without `components`.
### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": "Bill of materials not found"}` | `bom_id` not found or not in your org. |
## MCP / assistant access
The Coverbase [MCP server](/mcp/overview) exposes BOMs read-only through the `query_vendors` dispatcher tool, with no new top-level tools. Two new `kind` values join the existing ones (`documents`, `document_summary`, `risk_summary`, ...):
| `kind` | Returns | Args |
| - | - | - |
| `bill_of_materials` | The latest applied BOM for a vendor, plus its components | `vendor_id` (required), `limit` (max components, default `100`) |
| `bill_of_materials_history` | All uploaded BOMs for a vendor, newest first (the first is the applied one) | `vendor_id` (required), `limit` (default `20`) |
Both are user- and org-scoped. See [example prompts](/mcp/example-prompts#bill-of-materials) for natural-language phrasings.
## Availability
Bill of Materials is available to every organization: the **Bill of Materials** tab appears on each vendor and service page, and no entitlement is required. Because these are dashboard endpoints, call them with a signed-in user's session token rather than an `ak_` API key.
# Contract records API
Source: https://docs.coverbase.com/api-reference/contract-records
List, read, create and update contract metadata from a GRC, orchestration or reporting tool: type, counterparty, term dates, renewal, notice period, value, workflow state and linked engagements.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Your Coverbase representative turns on the third-party lifecycle features, including these routes, for your organization.
A **contract record** (`cbcontract_...`) is a contract's metadata: what it is, who it is with, its term, its value and where it is in your approval and signature process. This API lets another system of record read and keep that metadata in step. Documents, clause analyses and approval chains stay on the dashboard.
These routes are `/v1/contract-records`. The similar-looking `/v1/contracts` paths are dashboard routes and are not part of the public API. While the third-party lifecycle features are off for your organization, every route here returns `404` with `not_enabled`.
All endpoints are org-scoped to the credential: an `ak_*` key or an [OAuth token](/api-reference/oauth). See [API conventions](/conventions) for shared behavior. None of these honor `Idempotency-Key`.
| Method | Path | Permission |
| - | - | - |
| `GET` | `/v1/contract-records` | Read contracts |
| `GET` | `/v1/contract-records/{contract_id}` | Read contracts |
| `POST` | `/v1/contract-records` | Create contracts |
| `PATCH` | `/v1/contract-records/{contract_id}` | Update contracts (and archive contracts, to change `is_archived`) |
## List contract records
`GET /v1/contract-records`
Newest first. Uses the standard [pagination](/conventions#pagination) envelope: `{ "items": [...], "total", "limit", "offset" }`.
Only contracts with this vendor (`cbvndr_...`).
1 to 200.
0 or more.
```bash cURL theme={null}
curl "https://api.coverbase.app/v1/contract-records?vendor_id=cbvndr_e448ba62882143f3ba0c140bb2e30162&limit=50" \
-H "Authorization: Bearer ak_live_xxx"
```
## Get a contract record
`GET /v1/contract-records/{contract_id}`
Returns the [contract record object](#the-contract-record-object), archived ones included. An unknown ID returns `404 contract_not_found`.
## Create a contract record
`POST /v1/contract-records`
Returns `201 Created` with the [contract record object](#the-contract-record-object). The contract is created commercially active, in the `draft` workflow state.
1 to 500 characters.
One of `msa`, `sow`, `order_form`, `amendment`, `nda`, `dpa`, `baa`, `subscription_agreement`, `license_agreement`, `services_agreement`, `reseller_agreement`, `statement_of_services`, `letter_of_intent`, `renewal`, `api_integration_agreement`, `data_sharing_agreement`, `eula`, `addendum`, `appendix`, `other`.
The vendor (`cbvndr_...`). An unknown vendor returns `400 vendor_not_found`.
The other party's name, up to 500 characters, for a contract with no vendor record.
Up to 10,000 characters.
Unix seconds.
Unix seconds.
Unix seconds. The effective date, term start and expiration must be in order, or the request returns `422 invalid_term`.
Unix seconds.
`none`, `automatic` or `manual`.
0 or more.
0 or more.
A three-letter currency code.
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/contract-records" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme master services agreement",
"contract_type": "msa",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"effective_date": 1767225600,
"expiration_date": 1830297600,
"auto_renew": "manual",
"termination_notice_period_days": 90,
"contract_value_amount": 250000,
"contract_value_currency": "USD"
}'
```
## Update a contract record
`PATCH /v1/contract-records/{contract_id}`
Changes only the fields you send; omitted fields are unchanged. Accepts `name`, `description`, `contract_type`, `effective_date`, `term_start_date`, `expiration_date`, `renewal_date`, `auto_renew`, `termination_notice_period_days`, `contract_value_amount`, `contract_value_currency` and `is_archived`, with the same rules as create. Changing `is_archived` also needs permission to archive contracts. Every changed field is recorded in the contract's activity log.
The workflow state cannot be set through this API. A contract becomes `executed` only through Coverbase's signature engines or a connected contract lifecycle system.
## The contract record object
```json theme={null}
{
"id": "cbcontract_5f0c2b1e9d8a4c7b8e6f1a2b3c4d5e6f",
"name": "Acme master services agreement",
"description": null,
"contract_type": "msa",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"counterparty_name": null,
"parent_contract_id": null,
"workflow_state": "draft",
"lifecycle_status": null,
"effective_date": 1767225600,
"term_start_date": null,
"expiration_date": 1830297600,
"renewal_date": null,
"auto_renew": "manual",
"termination_notice_period_days": 90,
"contract_value_amount": "250000",
"contract_value_currency": "USD",
"executed_at": null,
"engagement_ids": ["cbegm_0a1b2c3d4e5f60718293a4b5c6d7e8f9"],
"is_archived": false,
"created_at": 1790000000,
"updated_at": 1790000000
}
```
Where the contract is in your process: `draft`, `pending_approval`, `approved`, `sent_for_signature`, `executed`, `rejected` or `terminated`. Only `executed` asserts that a signature exists. Contracts that predate the workflow read `draft`.
The label of the contract's status in your organization's status list, if one is set.
When it was executed, in Unix seconds.
The [engagements](/api-reference/engagement-records) linked to this contract.
A decimal, serialized as a string to keep its precision.
# Custom Fields API
Source: https://docs.coverbase.com/api-reference/custom-fields
Discover your organization's custom field definitions and read their values on vendors, services, and assessments.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A **custom field** (`cbcfc_...`) is a field your organization defines on top of Coverbase's built-in ones: a risk exception owner, an internal tier, a review date. This API lets an integration discover which fields exist and read the values set on your records.
Values are returned on vendors, services, and assessments. Use `GET /v1/custom-fields` first to learn the `config_id`, type, and allowed options behind each value.
All endpoints are org-scoped to the API key. See [API conventions](/conventions) for shared behavior.
| Method | Path |
| - | - |
| `GET` | `/v1/custom-fields` |
| `POST` | `/v1/custom-fields/values` |
Definitions themselves are managed in the Coverbase dashboard. This API reads them, and reads or writes the **values** set against your records.
## List custom field definitions
`GET /v1/custom-fields`
### Query parameters
Only return fields that apply to this object type. One of `vendor`, `service`, `assessment`, `control`, `eval`, `contract`, `task`, `review`, `engagement`. An unrecognized value returns `422`.
Include fields your organization has disabled. Default `false`.
### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/custom-fields?target=vendor" \
-H "Authorization: Bearer ak_live_xxx"
```
### Example response
```json theme={null}
{
"items": [
{
"id": "cbcfc_4f2a9c1b7d3e0a6b8c5d2e9f1a4b7c0d",
"field_name": "Risk Exception Owner",
"field_type": "user",
"enabled": true,
"applies_to": ["vendor"],
"options": [],
"created_at": 1749168000,
"updated_at": 1749168000
},
{
"id": "cbcfc_8b1e4a7d0c3f6a9b2e5d8c1f4a7b0e3d",
"field_name": "Exception Status",
"field_type": "select",
"enabled": true,
"applies_to": ["vendor", "engagement"],
"options": [
{ "label": "Open", "color": "amber" },
{ "label": "Closed", "color": "green" }
],
"created_at": 1749168000,
"updated_at": 1752019200
}
],
"total": 2
}
```
### Response fields
The field's `config_id` (`cbcfc_...`). This is the value that appears as `config_id` on each custom field value.
The display name your organization gave the field. Names can be renamed at any time, so match on `id` rather than `field_name`.
One of `string`, `number`, `boolean`, `date`, `user`, `select`, `multiselect`. Determines the shape of `value` wherever this field appears.
Whether the field is currently in use. Disabled fields are excluded unless you pass `include_disabled=true`, and their values never appear on records.
The object types this field can be set on.
For `select` and `multiselect`, the allowed `label` values (each with an optional `color`). Empty for every other type.
## Where values appear
Set values are returned as a `custom_fields` array on these endpoints:
| Endpoint | Values included |
| - | - |
| `GET /v1/vendors/{vendor_id}` | Always, for the vendor and each nested service |
| `PATCH /v1/vendors/{vendor_id}` | Always |
| `GET /v1/vendors` | Only when `include_custom_fields=true` |
| `PATCH /v1/vendors/{vendor_id}/services/{service_id}` | Always |
| `GET /v1/assessments/{assessment_id}` | Always |
Listing vendors leaves values out by default so paging stays cheap; pass `include_custom_fields=true` when you need them.
Create responses return an empty `custom_fields` array, since a record has no values at the moment it is created.
### Example
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/vendors?include_custom_fields=true&limit=50" \
-H "Authorization: Bearer ak_live_xxx"
```
```json theme={null}
{
"items": [
{
"id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"name": "Acme Supplier",
"custom_fields": [
{
"config_id": "cbcfc_8b1e4a7d0c3f6a9b2e5d8c1f4a7b0e3d",
"field_name": "Exception Status",
"field_type": "select",
"value": "Open"
},
{
"config_id": "cbcfc_4f2a9c1b7d3e0a6b8c5d2e9f1a4b7c0d",
"field_name": "Risk Exception Owner",
"field_type": "user",
"value": ["cbuser_3e6f9a2b5c8d1e4f7a0b3c6d9e2f5a8b"]
}
]
}
],
"total": 1,
"limit": 50,
"offset": 0
}
```
### Value types
`value` is typed by `field_type`:
| `field_type` | `value` shape | Example |
| - | - | - |
| `string` | string | `"Renewal pending"` |
| `date` | string | `"2026-03-01"` |
| `select` | string, one of the field's option labels | `"Open"` |
| `number` | number | `4` |
| `boolean` | boolean | `true` |
| `multiselect` | string array of option labels | `["PII", "PCI"]` |
| `user` | string array of user IDs (`cbuser_...`) | `["cbuser_3e6f..."]` |
Resolve `user` IDs to names and emails through the [Users API](/api-reference/users).
## Set custom field values
`POST /v1/custom-fields/values`
Sets one or more values on a single record. Only the fields you name change; anything already set and not listed is left alone.
Writes are supported on the same records that return values: `vendor`, `service`, and `assessment`. A value can never be written somewhere it cannot be read back.
### Body
`vendor`, `service`, or `assessment`.
The record to set values on. Must exist and belong to your organization, or the call returns `404`.
One to 100 `{ "config_id": "cbcfc_...", "value": ... }` entries. A `config_id` may appear only once per request.
Note that you do **not** send `field_type`. The field's own definition is authoritative, which is what stops a value being written into the wrong typed column.
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/custom-fields/values" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"target": "vendor",
"object_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"values": [
{ "config_id": "cbcfc_8b1e4a7d0c3f6a9b2e5d8c1f4a7b0e3d", "value": "Closed" },
{ "config_id": "cbcfc_4f2a9c1b7d3e0a6b8c5d2e9f1a4b7c0d", "value": ["cbuser_3e6f9a2b5c8d1e4f7a0b3c6d9e2f5a8b"] }
]
}'
```
### Example response
The record's full `custom_fields` array after the write:
```json theme={null}
{
"target": "vendor",
"object_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"custom_fields": [
{
"config_id": "cbcfc_8b1e4a7d0c3f6a9b2e5d8c1f4a7b0e3d",
"field_name": "Exception Status",
"field_type": "select",
"value": "Closed"
}
]
}
```
### Clearing a value
Send `null` to empty a field. The field then drops out of `custom_fields` entirely, since only set values are returned.
```json theme={null}
{ "config_id": "cbcfc_8b1e4a7d0c3f6a9b2e5d8c1f4a7b0e3d", "value": null }
```
### Validation
Every assignment in the request is checked before any of them is written, so a request naming one bad field changes nothing at all. Errors from this endpoint return `detail` as a plain string that names the field, for example `{"detail": "'Review Date' expects an ISO date (YYYY-MM-DD)."}`.
| Status | When |
| - | - |
| 400 | A value's type doesn't match the field (`number` into a `string` field, and so on), or a `date` value is not an ISO date (`YYYY-MM-DD`) |
| 400 | A `select` or `multiselect` value isn't one of the field's configured option labels |
| 400 | A `user` value names a user ID that doesn't exist in your organization |
| 400 | The field doesn't apply to the given `target`, or has been disabled or archived |
| 400 | The same `config_id` appears twice in one request |
| 404 | The `object_id` or a `config_id` doesn't exist in your organization |
A write through this API behaves like a person editing the record in the dashboard: it takes precedence over values previously filled in by Coverbase's automated extraction.
## Behavior worth knowing
* **Only set values are returned.** A record with nothing filled in returns an empty `custom_fields` array, and a field left blank on a record is omitted rather than returned with a `null` value.
* **Disabled and archived fields are hidden.** Their values stay in Coverbase but never appear on API responses, so retiring a field cleanly removes it from your integration.
* **Match on `config_id`, not `field_name`.** Display names are editable in the dashboard and change with no deploy.
## Reading custom fields from an AI assistant
The [Coverbase MCP server](/mcp/overview) exposes the same data to AI assistants. Custom field values are already included in vendor, service, assessment, control, and engagement reads, and `query_platform(kind="custom_fields")` lists the definitions.
# Documents API
Source: https://docs.coverbase.com/api-reference/documents
Upload vendor documents, link them to vendors, services, and assessments, and download them.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A **document** (`cbvdoc_...`) is an evidence file (SOC 2 report, pentest report, policy, contract, questionnaire, diagram, ...) that belongs to a **vendor** (`cbvndr_...`). A document can additionally be linked to any number of that vendor's **services** (`cbsvc_...`) and **assessments** (`cbqsrw_...`).
Use this API to upload a document, attach it where it belongs, list and inspect documents, fetch a short-lived download URL, re-link, and archive.
All endpoints are org-scoped to the API key. See [API conventions](/conventions) for authentication, IDs, timestamps, idempotency, pagination, and the error envelope.
| Method | Path | Idempotent |
| - | - | - |
| `POST` | `/v1/documents` | Yes (`Idempotency-Key`) |
| `GET` | `/v1/documents` | - |
| `GET` | `/v1/documents/{document_id}` | - |
| `GET` | `/v1/documents/{document_id}/download` | - |
| `PATCH` | `/v1/documents/{document_id}` | No |
| `DELETE` | `/v1/documents/{document_id}` | No |
**Smart limits.** Uploads are capped at **100 MiB** per file. Allowed file
types: `pdf`, `doc`, `docx`, `rtf`, `txt`, `md`, `xls`, `xlsx`, `xlsm`, `csv`,
`ppt`, `pptx`, `png`, `jpg`, `jpeg`, `gif`, `webp`, `zip`, `msg`, `eml`. Anything
else is rejected with `400 unsupported_file_type`; an oversized file is rejected
with `413 file_too_large`. List responses page at `limit` 1-200 (default 50).
## Upload a document
`POST /v1/documents`
Uploads a file and creates a document attached to a vendor. The request is
`multipart/form-data`: send the file plus its links in one call. Returns
`201 Created` with the document object.
After upload, Coverbase asynchronously classifies the document (and, where
applicable, runs AI analysis). The returned `status` reflects this in-progress
state; poll `GET /v1/documents/{document_id}` to observe it settle.
### Form fields
The document file (`multipart/form-data` part).
The owning vendor ID (`cbvndr_...`).
Service IDs (`cbsvc_...`) to link the document to. Repeat the form field once
per service.
Assessment IDs (`cbqsrw_...`) to attach the document to as supporting evidence.
Optional document type slug (for example, `soc2_type2_auditor_report`,
`penetration_test_report`, `commercial_contract`). Omit it to let Coverbase
infer the type from the file. An unknown slug returns `422 invalid_document_type`.
Optional display name. Defaults to the uploaded filename.
### Headers
`Bearer ak_...`
Optional. Replaying the same key within 24 hours returns the original `201` body. See [Idempotency](/conventions#idempotency).
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/documents" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Idempotency-Key: acme-soc2-2026q1" \
-F "file=@./acme_soc2.pdf;type=application/pdf" \
-F "vendor_id=cbvndr_e448ba62882143f3ba0c140bb2e30162" \
-F "service_ids=cbsvc_1a2b" \
-F "assessment_ids=cbqsrw_9f8e" \
-F "document_type=soc2_type2_auditor_report" \
-F "name=ACME SOC 2 Type II"
```
```python Python theme={null}
import os
import requests
API_KEY = os.environ["COVERBASE_API_KEY"]
BASE_URL = "https://api.coverbase.app"
with open("acme_soc2.pdf", "rb") as fh:
resp = requests.post(
f"{BASE_URL}/v1/documents",
headers={
"Authorization": f"Bearer {API_KEY}",
"Idempotency-Key": "acme-soc2-2026q1",
},
data={
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"service_ids": ["cbsvc_1a2b"],
"assessment_ids": ["cbqsrw_9f8e"],
"document_type": "soc2_type2_auditor_report",
"name": "ACME SOC 2 Type II",
},
files={"file": ("acme_soc2.pdf", fh, "application/pdf")},
timeout=120,
)
resp.raise_for_status()
print(resp.json())
```
### Example response
`201 Created`: the document object:
```json theme={null}
{
"id": "cbvdoc_2f1c9a7b6d5e4f3a2b1c0d9e8f7a6b5c",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"name": "ACME SOC 2 Type II",
"extension": "pdf",
"size": 482113,
"document_type": "soc2_type2_auditor_report",
"status": "created",
"service_ids": ["cbsvc_1a2b"],
"assessment_ids": ["cbqsrw_9f8e"],
"created_at": 1749340800,
"updated_at": 1749340800
}
```
## The document object
Document ID (`cbvdoc_...`).Owning vendor ID.Display name.Normalized file extension (no leading dot).File size in bytes.The classified/declared document type slug, or `null` if not yet classified.Processing status (for example, `created`, `analyzing`, `complete`).Linked service IDs.Assessments the document is attached to.Creation time (Unix epoch seconds).Last-update time (Unix epoch seconds).
## List documents
`GET /v1/documents`
Returns a paginated list of documents. Combine the filters to narrow the result.
Only documents owned by this vendor.Only documents linked to this service.Only documents attached to this assessment.Page size, 1-200 (default 50).Pagination offset (default 0).
```bash cURL theme={null}
curl "https://api.coverbase.app/v1/documents?vendor_id=cbvndr_e448ba62882143f3ba0c140bb2e30162&limit=50" \
-H "Authorization: Bearer ak_live_xxx"
```
```json theme={null}
{
"data": [ { "id": "cbvdoc_...", "vendor_id": "cbvndr_...", "name": "ACME SOC 2 Type II", "...": "..." } ],
"total": 1,
"limit": 50,
"offset": 0
}
```
## Get a document
`GET /v1/documents/{document_id}`
Returns a single document's metadata and links, or `404 document_not_found`.
```bash cURL theme={null}
curl "https://api.coverbase.app/v1/documents/cbvdoc_2f1c9a7b6d5e4f3a2b1c0d9e8f7a6b5c" \
-H "Authorization: Bearer ak_live_xxx"
```
## Download a document
`GET /v1/documents/{document_id}/download`
Returns a short-lived (one hour) presigned URL for the document's file. Follow
the returned `url` with a plain `GET` (no `Authorization` header) to fetch the
bytes; it serves the file as an attachment with the original filename.
```bash cURL theme={null}
# 1. Get the presigned URL
curl "https://api.coverbase.app/v1/documents/cbvdoc_2f1c.../download" \
-H "Authorization: Bearer ak_live_xxx"
# 2. Follow it to download the file
curl -L -o acme_soc2.pdf "https://"
```
```json theme={null}
{
"url": "https://.s3.amazonaws.com/?X-Amz-Signature=...",
"filename": "ACME SOC 2 Type II.pdf",
"expires_in": 3600
}
```
## Update a document
`PATCH /v1/documents/{document_id}`
Updates the name, type, and links. All fields are optional; omitted fields are
left unchanged. Supplying a list for `service_ids` / `assessment_ids`
**replaces** the existing set (pass `[]` to clear it).
Replacement display name.Replacement document type slug.Replaces the set of linked services.Replaces the set of attached assessments.
```bash cURL theme={null}
curl -X PATCH "https://api.coverbase.app/v1/documents/cbvdoc_2f1c..." \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "service_ids": ["cbsvc_1a2b", "cbsvc_3c4d"], "assessment_ids": ["cbqsrw_9f8e"] }'
```
## Archive a document
`DELETE /v1/documents/{document_id}`
Archives (soft-deletes) the document. The underlying record is retained for
audit but no longer appears in list results.
```bash cURL theme={null}
curl -X DELETE "https://api.coverbase.app/v1/documents/cbvdoc_2f1c..." \
-H "Authorization: Bearer ak_live_xxx"
```
```json theme={null}
{ "id": "cbvdoc_2f1c...", "is_archived": true, "archived_at": 1749427200 }
```
## Attaching documents to assessments
There are three ways to link a document to an assessment:
1. **At upload time**: pass `assessment_ids` to `POST /v1/documents` (or
`service_ids` to attach to services).
2. **At assessment-create time**: upload the document first, then pass its ID
in `supporting_document_ids` when calling
[`POST /v1/assessments`](/api-reference/assessments).
3. **Later**: `PATCH /v1/documents/{document_id}` with `assessment_ids` /
`service_ids`.
## Errors
| Status | `code` | When |
| - | - | - |
| `400` | `unsupported_file_type` | The file extension is not in the allowlist. |
| `400` | `invalid_extension` | No file extension could be read from the file name. |
| `400` | `empty_file` | The uploaded file is empty. |
| `413` | `file_too_large` | The file exceeds the 100 MiB limit. |
| `422` | `invalid_document_type` | `document_type` is not a known slug. |
| `404` | `vendor_not_found` | The `vendor_id` does not exist in your org. |
| `404` | `document_not_found` | The document does not exist in your org. |
| `404` | `assessment_not_found` | A filtered `assessment_id` does not exist. |
| `409` | `document_not_ready` | The document has no stored file to download yet. |
See the [error envelope](/conventions#errors) for the response shape.
# Engagement records API
Source: https://docs.coverbase.com/api-reference/engagement-records
List and read engagements, the per-relationship record between your organization and a vendor: status, inherent and residual risk level, dates, services and contracts.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Your Coverbase representative turns on the third-party lifecycle features, including these routes, for your organization.
An **engagement record** (`cbegm_...`) is one piece of business with a vendor: the service a Transaction Owner is buying. This API lets a GRC, orchestration or reporting tool read engagements, their status and risk level, and the services and contracts they cover. It is read-only.
These routes are `/v1/engagement-records`. The similar-looking `/v1/engagements` paths are dashboard routes and are not part of the public API. While the third-party lifecycle features are off for your organization, every route here returns `404` with `not_enabled`.
All endpoints are org-scoped to the credential: an `ak_*` key or an [OAuth token](/api-reference/oauth), and need permission to read vendors. See [API conventions](/conventions) for shared behavior.
| Method | Path |
| - | - |
| `GET` | `/v1/engagement-records` |
| `GET` | `/v1/engagement-records/{engagement_id}` |
## List engagement records
`GET /v1/engagement-records`
Uses the standard [pagination](/conventions#pagination) envelope: `{ "items": [...], "total", "limit", "offset" }`.
Only engagements with this vendor (`cbvndr_...`).
1 to 200.
0 or more.
```bash cURL theme={null}
curl "https://api.coverbase.app/v1/engagement-records?vendor_id=cbvndr_e448ba62882143f3ba0c140bb2e30162" \
-H "Authorization: Bearer ak_live_xxx"
```
## Get an engagement record
`GET /v1/engagement-records/{engagement_id}`
Returns the [engagement record object](#the-engagement-record-object), archived ones included. An unknown ID returns `404 engagement_not_found`.
## The engagement record object
```json theme={null}
{
"id": "cbegm_0a1b2c3d4e5f60718293a4b5c6d7e8f9",
"name": "Acme payroll processing",
"description": null,
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"status": "Active",
"status_group": "started",
"inherent_risk_level": "High",
"residual_risk_level": "Medium",
"start_date": 1767225600,
"end_date": null,
"service_ids": ["cbsvc_9f8e7d6c5b4a39281706f5e4d3c2b1a0"],
"contract_ids": ["cbcontract_5f0c2b1e9d8a4c7b8e6f1a2b3c4d5e6f"],
"is_archived": false,
"created_at": 1767225600,
"updated_at": 1790000000
}
```
The label of the engagement's status in your organization's status list.
The group the status belongs to: `unstarted`, `started`, `completed` or `canceled`. It does not change when your organization renames statuses, so use it, not the label, in integration logic.
The name of the engagement's inherent risk level.
The name of the engagement's residual risk level.
The vendor services (`cbsvc_...`) the engagement covers.
The [contract records](/api-reference/contract-records) linked to the engagement.
# Findings API
Source: https://docs.coverbase.com/api-reference/findings
List, create, retrieve, and status-sync findings for GRC round-trips.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A **finding** (`cbtask_...`) is an issue raised against a vendor or an assessment. This API exists for GRC sync and external visibility: pull findings into your GRC tool, push status changes back.
Findings are internally modeled as "tasks", so finding IDs use the `cbtask_` prefix. A `cbtask_...` value **is** a finding ID.
All endpoints are org-scoped to the API key. See [API conventions](/conventions) for shared behavior, including [pagination](/conventions#pagination).
| Method | Path |
| - | - |
| `GET` | `/v1/findings` |
| `POST` | `/v1/findings` |
| `GET` | `/v1/findings/{finding_id}` |
| `PATCH` | `/v1/findings/{finding_id}` |
None of these honor `Idempotency-Key`.
## List findings
`GET /v1/findings`
### Query parameters
Filter to findings on a vendor (`cbvndr_...`).
Filter to findings on an assessment (`cbqsrw_...`).
Page size. Default `50`, range `1`-`200`.
Page offset. Default `0`.
### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/findings?vendor_id=cbvndr_e448ba62882143f3ba0c140bb2e30162&limit=50&offset=0" \
-H "Authorization: Bearer ak_live_xxx"
```
### Example response
```json theme={null}
{
"items": [
{
"id": "cbtask_9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d",
"public_idx": "F-142",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"assessment_id": "cbqsrw_2d5e8f1a4b7c0d3e6f9a2b5c8d1e4f7a",
"finding_status_id": "cbst_open1234567890abcdef1234567890ab",
"due_date": 1749168000,
"is_archived": false,
"created_at": 1746576000,
"updated_at": 1746576400
}
],
"total": 1,
"limit": 50,
"offset": 0
}
```
### Finding object
Finding ID (`cbtask_...`).Human-readable index (for example, `F-142`), if assigned.Vendor the finding is on, if any.Assessment the finding is on, if any.Status record ID (`cbst_...`).Unix timestamp (seconds), if set.`true` if archived.Unix timestamp (seconds).Unix timestamp (seconds).
The list envelope adds `total` (full filtered count), `limit`, and `offset`; see [pagination](/conventions#pagination).
## Create a finding
`POST /v1/findings`
Returns `201 Created`. **Exactly one of `vendor_id` or `assessment_id` must be provided**; supplying neither *or both* is rejected with `422` ("Exactly one of vendor\_id or assessment\_id must be provided.").
### Request body
Finding title.
Finding detail / description.
Vendor the finding is raised against (`cbvndr_...`). Provide this **or** `assessment_id`, not both.
Assessment the finding is raised against (`cbqsrw_...`). Provide this **or** `vendor_id`, not both.
Initial status record ID (`cbst_...`).
Unix timestamp (seconds).
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/findings" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"title": "Missing SOC 2 Type II report",
"body": "Vendor has not provided a current SOC 2 Type II.",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"due_date": 1749168000
}'
```
Returns the [finding object](#finding-object).
### Error responses
| Status | Body | When |
| - | - | - |
| 422 | Standard validation error (`msg`: "Exactly one of vendor\_id or assessment\_id must be provided.") | Neither or both of `vendor_id`/`assessment_id` supplied, `title` missing, or body malformed. |
| 400 | `{"detail": {"code": "invalid_finding", "message": "..."}}` | Business-rule rejection (for example, a bad reference ID). |
| 403 | `{"detail": "Findings are not enabled for this organization."}` | A vendor-level finding (`vendor_id`) was requested and your organization does not have the **Findings** page enabled. Findings on an assessment are always allowed. |
## Retrieve a finding
`GET /v1/findings/{finding_id}`
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/findings/cbtask_9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d" \
-H "Authorization: Bearer ak_live_xxx"
```
Returns the [finding object](#finding-object).
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "finding_not_found", "message": "Finding not found."}}` | Not found / not in the API key's org. |
## Update / status-sync a finding
`PATCH /v1/findings/{finding_id}`
Designed for the GRC round-trip: push status and due-date changes (or archive) back into Coverbase. Only included fields change.
### Request body
New status record ID (`cbst_...`).
New due date (Unix seconds).
Archive (`true`) or restore (`false`) the finding.
### Example request
```bash cURL theme={null}
curl -X PATCH "https://api.coverbase.app/v1/findings/cbtask_9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "finding_status_id": "cbst_resolved234567890abcdef1234567890" }'
```
Returns the refreshed [finding object](#finding-object).
### Error responses
| Status | Body | When |
| - | - | - |
| 400 | `{"detail": {"code": "invalid_update", "message": "..."}}` | Update rejected (for example, invalid status ID). |
| 404 | `{"detail": {"code": "finding_not_found", "message": "Finding not found."}}` | Not found / not in the API key's org. |
| 422 | Standard validation error | Body failed schema validation. |
# Intake API
Source: https://docs.coverbase.com/api-reference/intake
Create vendor intake requests programmatically, pass unstructured context, and let Coverbase auto-answer the inherent risk questionnaire.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
An **intake session** (`cbintksn_...`) is a vendor intake request. Creating one through this API registers the vendor, creates the intake session, and kicks off AI processing that auto-answers the selected inherent risk questionnaire(s). With `auto_submit`, the session is then submitted to the dashboard's **Intake** queue, where reviewers approve or deny it; on approval, the questionnaire-derived inherent risk scores are applied to the vendor and its services.
Use this API to embed Coverbase intake inside another system (procurement tool, ticketing, internal portal): POST the request (including any free-form context and files you already have) and poll for the generated answers.
All endpoints are org-scoped to the API key. See [API conventions](/conventions) for authentication, IDs, timestamps, and the error envelope.
**Not embedding intake in another system?** The same request can be filed conversationally through the MCP server, with the assistant researching the vendor, confirming its identity, running your configured screening, and walking the questionnaire with the requester. See [Vendor intake in chat](/mcp/vendor-intake). Both paths produce the same session and the same review queue.
| Method | Path | Idempotent |
| - | - | - |
| `GET` | `/v1/intake/api/questionnaires` | - |
| `POST` | `/v1/intake/api/documents` | Yes (`Idempotency-Key`) |
| `POST` | `/v1/intake/api/sessions` | Yes (`external_id`) |
| `GET` | `/v1/intake/api/sessions/{session_id}` | - |
| `GET` | `/v1/intake/api/sessions/external/{external_id}` | - |
## List questionnaires
`GET /v1/intake/api/questionnaires`
Lists your organization's questionnaires so you can discover the IDs to pass as
`questionnaire_ids` when [creating an intake session](#create-an-intake-session).
Archived questionnaires are excluded.
### Query parameters
Optional. Filter to a single questionnaire type, for example, `irq` (inherent risk
questionnaire), `vendor_onboarding`, `assessment`, `informational`.
### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/intake/api/questionnaires?type=irq" \
-H "Authorization: Bearer ak_live_xxx"
```
### Example response
`200 OK`:
```json theme={null}
{
"items": [
{
"id": "cbqsr_709ae0e1e2f542e98b481d42276dcda1",
"name": "Inherent Risk Questionnaire",
"description": "Default IRQ applied at intake.",
"type": "irq",
"created_at": 1746576000
}
],
"total": 1
}
```
The org's questionnaires. Each has `id` (`cbqsr_...`), `name`, `description`
(or `null`), `type`, and `created_at` (Unix seconds).
Number of questionnaires returned.
## Upload a document
`POST /v1/intake/api/documents`
Uploads a file you want an intake to read, such as a SOC 2 report, a security
questionnaire, or architecture notes from the procurement ticket. Returns
`201 Created` with a `document_id` (`cbodoc_...`). Pass that ID in
`document_ids` when you [create the intake session](#create-an-intake-session).
This is the API equivalent of uploading files on the first step of the intake
portal.
Attaching files is a two-step flow:
1. Upload each file with this endpoint and keep the returned `document_id`.
2. Create the intake session with those IDs in `document_ids`.
The files are attached before Coverbase starts answering the questionnaire, so
every answer can draw on them. An upload you never name on an intake is not
used.
The body is `multipart/form-data`, one file per request. Uploads follow the
same limits as the [Documents API](/api-reference/documents): 100 MiB per file
and the same allowed file types.
### Which files inform the answers
Coverbase reads `pdf`, `doc`, `docx`, `txt`, `md`, `csv`, `xls` and `xlsx` files
when it answers the questionnaire. Other allowed types (`png`, `jpg`, `jpeg`,
`gif`, `webp`, `ppt`, `pptx`, `rtf`, `xlsm`, `zip`, `msg`, `eml`) are accepted
and kept as evidence, but they do not inform the answers. A file too long for
the model is also kept but skipped when answering. This matches how the intake
portal treats the same files.
### Form fields
The document file (`multipart/form-data` part). The file name's extension
decides the file type.
Display name. Defaults to the file name.
### Headers
Optional. Replaying the same key within 24 hours returns the original `201`
body and stores no second file. A retry sent while the first request is still
uploading waits for it and returns the same response. See
[Idempotency](/conventions#idempotency).
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/intake/api/documents" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Idempotency-Key: PROC-4821-soc2" \
-F "file=@acme-soc2-type2.pdf" \
-F "name=Acme SOC 2 Type II (2026)"
```
```python Python theme={null}
import os
import requests
API_KEY = os.environ["COVERBASE_API_KEY"]
BASE_URL = "https://api.coverbase.app"
with open("acme-soc2-type2.pdf", "rb") as f:
resp = requests.post(
f"{BASE_URL}/v1/intake/api/documents",
headers={
"Authorization": f"Bearer {API_KEY}",
"Idempotency-Key": "PROC-4821-soc2",
},
files={"file": ("acme-soc2-type2.pdf", f, "application/pdf")},
data={"name": "Acme SOC 2 Type II (2026)"},
)
resp.raise_for_status()
document_id = resp.json()["document_id"]
```
### Example response
`201 Created`:
```json theme={null}
{
"document_id": "cbodoc_3f9a1c2e7b5d4e6f8a0b1c2d3e4f5a6b",
"name": "Acme SOC 2 Type II (2026)",
"extension": "pdf",
"size": 2411200,
"created_at": 1765432050
}
```
The uploaded document (`cbodoc_...`). Pass it in `document_ids`.
Display name.Normalized file extension (no leading dot).File size in bytes.Upload time (Unix seconds).
### Errors
| Status | `code` | When |
| - | - | - |
| `400` | `unsupported_file_type` | The file extension is not in the allowlist. |
| `400` | `invalid_extension` | No file extension could be read from the file name. |
| `400` | `empty_file` | The uploaded file is empty. |
| `413` | `file_too_large` | The file exceeds the 100 MiB limit. |
## Create an intake session
`POST /v1/intake/api/sessions`
Creates the vendor, the intake session, and one questionnaire response per
questionnaire, then dispatches asynchronous AI processing. Returns
`201 Created` with the new `session_id`. Unknown questionnaire IDs return
`404`, and so does an organization whose vendor intake is turned off. Replaying the same `external_id`
returns the existing `session_id` with `200 OK` and does not reprocess; the
original request's data (including `context` and `document_ids`) is retained,
and any changed fields in the replay are ignored. To analyze a vendor with updated context,
create a new request with a new `external_id`.
### Body fields
Name of the vendor the intake request is for.
Inherent risk questionnaire IDs (`cbqsr_...`) to auto-answer. At least one
is required; unknown IDs return `404`. Use
[`GET /v1/intake/api/questionnaires`](#list-questionnaires) to discover the
IDs available in your organization.
Unstructured free-form context about the engagement: procurement ticket
text, requester emails, architecture notes, security questionnaire excerpts,
anything. Coverbase uses it as the **highest-priority evidence** when
auto-answering the questionnaire (ahead of uploaded documents and web
research), so the inherent risk analysis is driven by what you already know
about the engagement. Maximum 100,000 characters. The context is persisted on
the intake session, so later reprocessing runs reuse it.
Roughly the first 20,000 characters are included in each
question's evidence (longer context is truncated per question), so put the
most decision-relevant facts first rather than padding toward the limit.
When your context exceeds that cap, the create response sets
`context_truncated: true`.
Documents (`cbodoc_...`) uploaded with
[`POST /v1/intake/api/documents`](#upload-a-document) to attach to this intake.
At most 20. Coverbase reads them as evidence when it answers the
questionnaire, and they move onto the vendor record when the intake is
submitted. Each document can be attached to one intake only. If any ID cannot
be attached, the request returns `422` with code `documents_unavailable`, a
`documents` list naming each ID with its `problem`, and creates nothing:
| `problem` | Meaning |
| - | - |
| `not_found` | No document with that ID exists in your organization. |
| `not_an_intake_upload` | The ID belongs to a document that was not uploaded with `POST /v1/intake/api/documents`. |
| `already_attached` | Another intake session already has the document. Upload the file again for a new intake. |
Public website of the vendor. Improves web research and disambiguation.
Short description of what the vendor does.
What your organization intends to use the vendor for.
Your identifier for this request (for example, the procurement ticket number).
Enforced unique per org; replays are idempotent and you can fetch the
session by this ID later.
Submit the session for review once auto-answering completes. The request
moves to **Pending review** in the **Intake** queue with its answers marked
ready for review, and a person still approves or denies it. Leave it `false`
to collect the answers over this API: the session stays a **Draft** and is
not submitted for review. Every questionnaire must be one an intake reviewer
can approve or deny; an `assessment` questionnaire returns `422`.
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/intake/api/sessions" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"vendor_name": "Acme Analytics",
"vendor_website": "https://acme-analytics.example",
"use_case": "Product analytics on first-party event data",
"questionnaire_ids": ["cbqsr_709ae0e1e2f542e98b481d42276dcda1"],
"external_id": "PROC-4821",
"context": "From procurement ticket PROC-4821: Acme will ingest pseudonymized product events (no payment data) via server-side SDK. Hosting is AWS us-east-1, single-tenant per customer. They hold SOC 2 Type II (report attached to the ticket) and support SAML SSO + SCIM. Estimated spend $40k/yr, business owner is the Growth team."
}'
```
```python Python theme={null}
import os
import requests
API_KEY = os.environ["COVERBASE_API_KEY"]
BASE_URL = "https://api.coverbase.app"
resp = requests.post(
f"{BASE_URL}/v1/intake/api/sessions",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"vendor_name": "Acme Analytics",
"vendor_website": "https://acme-analytics.example",
"use_case": "Product analytics on first-party event data",
"questionnaire_ids": ["cbqsr_709ae0e1e2f542e98b481d42276dcda1"],
"external_id": "PROC-4821",
"context": (
"From procurement ticket PROC-4821: Acme will ingest "
"pseudonymized product events (no payment data) via server-side "
"SDK. Hosting is AWS us-east-1, single-tenant per customer. They "
"hold SOC 2 Type II and support SAML SSO + SCIM."
),
},
)
resp.raise_for_status()
session_id = resp.json()["session_id"]
```
### Response
```json theme={null}
{
"session_id": "cbintksn_7c1d9e2b41f04c5e8a3b6d0f9e2c4a71",
"context_truncated": false
}
```
`context_truncated` is `true` when the submitted `context` exceeds the
per-question evidence cap; the full text is stored, but each question prompt
only receives the leading portion.
## Get an intake session
`GET /v1/intake/api/sessions/{session_id}`
Returns the session status and the per-question answers generated so far. Also
available by your own identifier:
`GET /v1/intake/api/sessions/external/{external_id}`.
### Session status
| `status` | Meaning |
| - | - |
| `pending` | Created; processing has not produced answers yet |
| `processing` | AI answering is in flight |
| `complete` | Answers generated. With `auto_submit`, the request is submitted for reviewer triage in the dashboard |
| `failed` | Processing failed for every question (for example, dispatch failure); contact support or retry with a new request |
Each entry in `answers[]` carries `question_id`, `question_text`,
`response_type` (`free_text`, `single_select`, `multi_select`), the generated
`answer_text` or `selected_options`, the model's `reasoning`, and a per-answer
`status` (`answered`, `pending`, `failed`). `failed_count` summarizes failed
answers.
`documents[]` lists the files attached with `document_ids`, in the order you
named them. Each entry carries `document_id`, `name`, `extension` and `size`.
Once the intake is submitted, each entry also carries `vendor_document_id`: the
vendor document (`cbvdoc_...`) the file became. Use it with
[`GET /v1/documents/{document_id}`](/api-reference/documents#get-a-document) for
the inferred document type, analysis status and a download link. Before submit
`vendor_document_id` is `null`.
`vendor_id` is the vendor (`cbvndr_...`) the request created or linked, or
`null` if no vendor is linked. Use it with the [Vendors API](/api-reference/vendors#retrieve-a-vendor)
or to match an assessment back to this request (see
[Find the assessment an intake leads to](#find-the-assessment-an-intake-leads-to)).
### Inherent risk score
Once `status` is `complete`, the response carries the questionnaire's inherent
risk score and tier, so your system can route the request without waiting for
review.
The inherent risk score of the session's IRQ answers, from 0 to 100. It is
calculated the same way approval scores the vendor, including your
organization's risk domain weights, aggregation method and option score
floors. When the session has several IRQs, this is the highest score, because
approval only ever raises the vendor's score. It is `null` until `status` is
`complete`, and `null` when no questionnaire on the session is a scored IRQ.
The level on your organization's default risk scale that `raw_irq_score`
falls in, named the way your scale names it (for example `Medium`). It is
`null` whenever `raw_irq_score` is `null`, and `null` if your organization has
no default risk scale.
Both fields follow the current answers. If a reviewer edits an answer before
approving, the score changes with it. If the reviewer overrides the score when
approving, the vendor record holds the override and these fields still report
the score calculated from the answers.
### Example response
```json theme={null}
{
"session_id": "cbintksn_7c1d9e2b41f04c5e8a3b6d0f9e2c4a71",
"external_id": "PROC-4821",
"status": "complete",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"vendor_name": "Acme Analytics",
"vendor_website": "https://acme-analytics.example",
"created_at": 1765432100,
"updated_at": 1765432190,
"failed_count": 0,
"raw_irq_score": 42.5,
"inherent_risk_level": "Medium",
"documents": [
{
"document_id": "cbodoc_3f9a1c2e7b5d4e6f8a0b1c2d3e4f5a6b",
"name": "Acme SOC 2 Type II (2026)",
"extension": "pdf",
"size": 2411200,
"vendor_document_id": "cbvdoc_8d2e4f6a1b3c4d5e9f0a7b6c5d4e3f2a"
}
],
"answers": [
{
"question_id": "cbqstn_91b2",
"question_text": "Will the vendor process personal data?",
"response_type": "single_select",
"answer_text": "Yes",
"selected_options": ["Yes"],
"reasoning": "The provided context states Acme ingests pseudonymized product events, which is personal data under GDPR.",
"status": "answered"
}
]
}
```
## Find the assessment an intake leads to
An intake session does not create an assessment, and its response does not
carry an assessment ID. Your organization's workflows decide whether an
assessment follows an intake, so one request can lead to no assessment or to
several. To pick up the assessment:
1. Subscribe a [webhook](/integrations/webhooks) to `Assessment.Created` and
`Assessment.Updated`. Each delivery carries the `assessment_id`.
2. Call [`GET /v1/assessments/{assessment_id}`](/api-reference/assessments#retrieve-an-assessment).
The response carries `vendor_id`, `status` and `score_percent`.
3. Match that `vendor_id` to the `vendor_id` on the intake session you created.
If your receiver misses deliveries, read them back from
[`GET /v1/webhooks/{webhook_id}/deliveries`](/integrations/webhook-deliveries).
It lists every attempt from the last 90 days with the payload that was sent.
## How context drives inherent risk
1. **Evidence assembly.** For every questionnaire question, Coverbase builds an
evidence stack ordered by reliability: your provided `context`, then intake
follow-up responses, then the documents you attached with `document_ids`,
then targeted web research.
2. **Auto-answering.** The answer agent answers each question from that
evidence, recording its reasoning per answer. Questions it cannot answer are
flagged for human review rather than guessed.
3. **Scoring & review.** The answered inherent risk questionnaire produces the
IRQ score and per-domain risk breakdown shown on the intake request in the
dashboard. The session response returns the same score and its risk level as
[`raw_irq_score` and `inherent_risk_level`](#inherent-risk-score). A reviewer
approves or denies the request; approval applies the inherent risk scores to
the vendor and its services.
Until it is submitted, an intake session created by this API is a **Draft**
that no reviewer is asked to act on. With `auto_submit`, it is submitted as
soon as its answers are generated and then follows the same triage and
approval flow in the dashboard's **Intake** queue as a portal-submitted
request.
# OAuth API
Source: https://docs.coverbase.com/api-reference/oauth
Exchange an OAuth 2.0 client's credentials for a short-lived bearer token at POST /v1/oauth/token, and manage OAuth clients.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Your Coverbase representative turns on the third-party lifecycle features, including OAuth clients, for your organization.
An integration that cannot store a long-lived `ak_*` key can use the OAuth 2.0 client credentials grant instead. An admin creates an **OAuth client**: a public `client_id` and a `client_secret` shown once. The integration trades them for a bearer token that lasts at most an hour, and sends that token wherever an `ak_*` key goes.
A token acts exactly like an `ak_*` key: it authenticates as your organization's API service account, every public route and the [IP allowlist](/conventions#api-ip-allowlist) apply unchanged, and its calls are recorded in the [public API audit log](/conventions#public-api-audit-log). It carries the [elevated scopes](/conventions#api-key-scopes) the client was granted, or fewer if the token request narrows them.
| Method | Path | Auth |
| - | - | - |
| `POST` | `/v1/oauth/token` | Client ID and secret |
| `GET` | `/v1/api-oauth-clients` | Admin JWT, or `ak_*` key with `keys:manage` |
| `POST` | `/v1/api-oauth-clients` | Admin JWT, or `ak_*` key with `keys:manage` |
| `POST` | `/v1/api-oauth-clients/{client_row_id}/revoke` | Admin JWT, or `ak_*` key with `keys:manage` |
For a walkthrough, see [OAuth 2.0 client credentials](/integrations/guides/oauth-client-credentials).
## Get a token
`POST /v1/oauth/token`
Follows RFC 6749 section 4.4. The body is form-encoded (`application/x-www-form-urlencoded`), not JSON. Send the client ID and secret as HTTP Basic credentials (preferred), or as `client_id` and `client_secret` form fields, but not both.
### Request body
Must be `client_credentials`.
Space-separated scopes to request. Optional. It can only narrow what the client was granted: asking for a scope the client does not hold fails with `invalid_scope`. Omit it to get every scope the client holds.
The client ID (`cbci_...`), when not sent in HTTP Basic.
The client secret (`cbcs_...`), when not sent in HTTP Basic.
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/oauth/token" \
-u "cbci_0123456789abcdef0123456789abcdef:cbcs_xxx" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&scope=audit:read"
```
### Example response
```json theme={null}
{
"access_token": "cbat_xxx",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "audit:read"
}
```
The response carries `Cache-Control: no-store`. Send the token as `Authorization: Bearer cbat_...` until `expires_in` seconds pass, then request a new one. A client holds at most 50 live tokens. Requesting a 51st revokes its oldest, so an integration should reuse a token until it expires rather than request one per call.
The bearer token, prefixed `cbat_`.
Always `Bearer`.
Lifetime in seconds: the client's token lifetime, between 300 and 3600.
The scopes the token carries, space-separated. Empty for a client with no elevated scopes.
### Errors
Errors follow RFC 6749 section 5.2, not the [coded envelope](/conventions#errors):
```json theme={null}
{ "error": "invalid_client", "error_description": "Client authentication failed" }
```
| Status | `error` | When |
| - | - | - |
| `400` | `unsupported_grant_type` | `grant_type` is missing or not `client_credentials`. |
| `400` | `invalid_scope` | The request asks for a scope the client was not granted. |
| `400` | `invalid_request` | The request uses HTTP Basic and also sends the secret as a form field, or the two name different clients. |
| `401` | `invalid_client` | The client is unknown or revoked, the secret is wrong, or the third-party lifecycle features are no longer on for your organization. Comes with `WWW-Authenticate: Basic realm="coverbase"`. |
## List clients
`GET /v1/api-oauth-clients`
Returns `{ "clients": [ ... ] }`, one [client object](#the-client-object) per client, revoked ones included. Secrets are never returned.
## Create a client
`POST /v1/api-oauth-clients`
Returns `201 Created` with the [client object](#the-client-object) plus `client_secret`. **This is the only time the secret is returned.** Coverbase stores only its SHA-256 digest and last four characters.
A label, 1 to 200 characters, such as "Archer sync".
Elevated scopes to grant: `keys:manage`, `audit:read`, `banking:read`, `review:sensitive_changes`. Granting any needs an admin dashboard JWT; any other caller gets `403 scope_grant_forbidden`. Omit for a client with standard access.
How long each token lives, 300 to 3600. Default 3600.
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/api-oauth-clients" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{ "name": "GRC sync", "scopes": ["audit:read"], "access_token_ttl_seconds": 900 }'
```
## Revoke a client
`POST /v1/api-oauth-clients/{client_row_id}/revoke`
Revokes the client and deletes every token it issued. Returns the [client object](#the-client-object) with `revoked_at` set. A server that already cached a token can keep accepting it for a few seconds. Creating and revoking clients are recorded in the activity log.
## The client object
The client's row ID, used in the revoke path.
The label.
The public client ID, prefixed `cbci_`.
The last four characters of the secret, to tell clients apart.
The elevated scopes granted.
Token lifetime in seconds.
Unix seconds.
When the client last obtained a token.
When it was revoked, or `null`.
# Obligations API
Source: https://docs.coverbase.com/api-reference/obligations
List, create, retrieve, and status-sync obligations (CUEC) for GRC round-trips.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
An **obligation** (`cboblg_...`) is a compliance obligation tracked against the org. Obligations created through this API are of type **CUEC** (complementary user-entity controls). This API exists for GRC sync and external visibility.
All endpoints are org-scoped to the API key. See [API conventions](/conventions) for shared behavior, including [pagination](/conventions#pagination).
| Method | Path |
| - | - |
| `GET` | `/v1/obligations` |
| `POST` | `/v1/obligations` |
| `GET` | `/v1/obligations/{obligation_id}` |
| `PATCH` | `/v1/obligations/{obligation_id}` |
None of these honor `Idempotency-Key`.
## Status values
The `status` field accepts exactly:
| Value | Meaning |
| - | - |
| `satisfied` | The obligation is met. |
| `not_satisfied` | The obligation is not met (default on create). |
| `pending_acknowledgement` | An internal control or a similar obligation matches the statement, but your organization requires a business unit to acknowledge it first. It becomes `satisfied` once that commitment is fulfilled. |
Any other value returns `400 invalid_status` listing the accepted values.
## List obligations
`GET /v1/obligations`
### Query parameters
Filter to obligations associated with a vendor (`cbvndr_...`).
Filter by status: `satisfied`, `not_satisfied`, or `pending_acknowledgement`.
Page size. Default `50`, range `1`-`200`.
Page offset. Default `0`.
### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/obligations?obligation_status=not_satisfied&limit=50" \
-H "Authorization: Bearer ak_live_xxx"
```
### Example response
```json theme={null}
{
"items": [
{
"id": "cboblg_4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c",
"statement": "Customer must enforce MFA on all admin accounts.",
"status": "not_satisfied",
"obligation_type": "cuec",
"compliance_type": null,
"vendor_document_id": "cbvdoc_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
"assignee_id": "cbuser_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"assignee_group_id": null,
"due_date": 1749168000,
"is_archived": false,
"created_at": 1746576000,
"updated_at": 1746576400
}
],
"total": 1,
"limit": 50,
"offset": 0
}
```
### Obligation object
Obligation ID (`cboblg_...`).The obligation statement.`satisfied`, `not_satisfied`, or `pending_acknowledgement`.Always `cuec` for obligations created via this API.How compliance is established (`manual`, `internal_control`, or `similar_obligation`), if set.Source vendor document (`cbvdoc_...`), if linked.Assigned user (`cbuser_...`).Assigned user group (`cbdept_...`), if assigned to a group instead of a user.Unix timestamp (seconds), if set.`true` if archived.Unix timestamp (seconds).Unix timestamp (seconds).
The list envelope adds `total`, `limit`, `offset`; see [pagination](/conventions#pagination).
## Create an obligation
`POST /v1/obligations`
Returns `201 Created`. `obligation_type` is always set to `cuec`.
### Request body
The obligation statement.
`satisfied`, `not_satisfied`, or `pending_acknowledgement`. Defaults to `not_satisfied`.
Link to a source vendor document (`cbvdoc_...`).
Assign to a user (`cbuser_...`).
Assign to a user group (`cbdept_...`) instead of a user. The group's assignment rule may pick a member, in which case the response carries that user in `assignee_id`.
Unix timestamp (seconds).
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/obligations" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"statement": "Customer must enforce MFA on all admin accounts.",
"status": "not_satisfied",
"due_date": 1749168000
}'
```
Returns the [obligation object](#obligation-object).
### Error responses
| Status | Body | When |
| - | - | - |
| 400 | `{"detail": {"code": "invalid_status", "message": "Invalid status '...'. Expected one of: satisfied, not_satisfied, pending_acknowledgement."}}` | `status` not one of the accepted values. |
| 400 | `{"detail": {"code": "invalid_obligation", "message": "..."}}` | Other business-rule rejection. |
| 422 | Standard validation error | `statement` missing or body malformed. |
## Retrieve an obligation
`GET /v1/obligations/{obligation_id}`
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/obligations/cboblg_4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c" \
-H "Authorization: Bearer ak_live_xxx"
```
Returns the [obligation object](#obligation-object).
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "obligation_not_found", "message": "Obligation not found."}}` | Not found / not in the API key's org. |
## Update / status-sync an obligation
`PATCH /v1/obligations/{obligation_id}`
Push status, assignment, due-date, or statement changes (or archive) back into Coverbase. Only included fields change.
### Request body
Updated statement.`satisfied`, `not_satisfied`, or `pending_acknowledgement`.Reassign to a user (`cbuser_...`).Reassign to a user group (`cbdept_...`).New due date (Unix seconds).Archive (`true`) or restore (`false`).
### Example request
```bash cURL theme={null}
curl -X PATCH "https://api.coverbase.app/v1/obligations/cboblg_4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "status": "satisfied" }'
```
Returns the refreshed [obligation object](#obligation-object).
### Error responses
| Status | Body | When |
| - | - | - |
| 400 | `{"detail": {"code": "invalid_status", "message": "Invalid status '...'. Expected one of: satisfied, not_satisfied, pending_acknowledgement."}}` | `status` not accepted. |
| 400 | `{"detail": {"code": "invalid_update", "message": "..."}}` | Update otherwise rejected. |
| 404 | `{"detail": {"code": "obligation_not_found", "message": "Obligation not found."}}` | Not found / not in the API key's org. |
| 422 | Standard validation error | Body failed schema validation. |
# Portals API
Source: https://docs.coverbase.com/api-reference/portals
List the requests you have sent to a vendor, each with the link the vendor uses to respond and whether it is still waiting on them.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A **portal** (`cbsbpt_...`) is one request sent to a vendor: an assessment's document collection and its follow-ups, a questionnaire, a findings and commitments request, an RFP, a case follow-up, or onboarding. Each request has its own link. These endpoints list the requests so your own systems can show a vendor everything still waiting on them, or sync request status into a partner portal, a CRM, or a ticketing tool.
The endpoints return only requests addressed to a vendor. Org-level portals (intake, vendor search), signing portals, and obligation commitments sent to your own stakeholders are never returned.
All endpoints are org-scoped to the credential: an `ak_*` key or an [OAuth token](/api-reference/oauth), and need permission to read portals. See [API conventions](/conventions) for shared behavior.
| Method | Path |
| - | - |
| `GET` | `/v1/portals` |
| `GET` | `/v1/portals/{portal_id}` |
## States
Each request carries a `state`, derived from its status, its due date, and whether you have paused it:
| State | Meaning |
| - | - |
| `open` | Waiting on the vendor. Includes a request you have paused and one whose answers are being analyzed. |
| `overdue` | Open, past its `due_at`, and not paused. |
| `submitted` | The vendor has submitted their response. |
| `closed` | You closed the request. |
`open` and `overdue` are the two states that need the vendor's attention.
## Request types
| `type` | What the vendor is asked for |
| - | - |
| `assessment` | Documents for an assessment, and its follow-up questions. |
| `informational` | A questionnaire with no assessment attached. |
| `irq` | An inherent risk questionnaire. |
| `findings_commitment` | Remediation commitments on findings you have shared. |
| `vendor_onboarding` | Onboarding details for a new vendor. |
| `rfp` | An RFP prequalification or response. |
| `case` | A follow-up on a monitoring case. |
## The link is not a credential
`url` is the same link the invitation email carries. Opening it still asks the recipient to sign in with an email address the request allows, so the link identifies the request; it does not grant access to it. Share it with the people you invited and it works the way the email did.
If you want each vendor to have one address for everything, turn on the [centralized supplier portal](/user-guides/centralized-supplier-portal). Every request keeps its own `url`, and the vendor also gets a single page listing all of them.
## List portals
`GET /v1/portals`
Lists requests in the API key's org, newest first. Without filters it returns every request addressed to a vendor, paginated.
### Query parameters
Only requests sent to this vendor (`cbvndr_...`). Resolve the id first with [`GET /v1/vendors`](/api-reference/vendors#list-vendors) by `external_id` or `name`.
Only requests in this state: `open`, `overdue`, `submitted`, or `closed`.
Only requests of this [type](#request-types).
Page size, 1-200.
Rows to skip.
### Example request
```bash cURL theme={null}
curl "https://api.coverbase.app/v1/portals?vendor_id=cbvndr_e448ba62882143f3ba0c140bb2e30162&state=open" \
-H "Authorization: Bearer ak_live_xxx"
```
### Example response
```json theme={null}
{
"items": [
{
"id": "cbsbpt_9c1f0e2a7b3d4e5f8a6b7c8d9e0f1a2b",
"reference": "WF-855",
"type": "assessment",
"state": "open",
"status": "open",
"url": "https://dashboard.coverbase.app/portal/k3x9q2m8v1",
"display_name": "Annual security review",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"assessment_id": "cbassm_1f2e3d4c5b6a79880a1b2c3d4e5f6a7b",
"due_at": 1762300800,
"paused": false,
"submitted_at": null,
"created_at": 1760313600
}
],
"total": 1,
"limit": 50,
"offset": 0
}
```
Rows are ordered by `created_at` descending, with ties broken by `id`, so paging with `offset` never repeats or skips a row.
### Portal object
Portal ID (`cbsbpt_...`).A short reference the vendor also sees, such as `WF-855`. Set once the [centralized supplier portal](/user-guides/centralized-supplier-portal) is on; `null` otherwise.The [request type](#request-types).`open`, `overdue`, `submitted`, or `closed`. See [States](#states).The stored status: `open`, `analyzing`, `analysis_complete`, `submitted`, or `closed`. Use `state` unless you need to tell the three open statuses apart.The link the vendor uses to respond. On a branded portal domain, the link uses that domain.The request's title as the vendor sees it.The vendor the request was sent to (`cbvndr_...`).The assessment this request collects for (`cbassm_...`), for `assessment` requests.Unix timestamp (seconds) the response is due, or `null` when no due date was set.`true` while you have put the request on hold. A paused request reads `open`, never `overdue`, and no reminders go out.Unix timestamp (seconds) of the vendor's first submission, or `null`.Unix timestamp (seconds).
## Retrieve a portal
`GET /v1/portals/{portal_id}`
Returns the [portal object](#portal-object), or `404 portal_not_found`. A portal that the list would not return (one with no vendor, or of a type outside the [request types](#request-types)) is also a `404`.
### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "portal_not_found", ...}}` | Not found, not in the API key's org, or not a vendor request. |
## Show a vendor their open requests
The common integration: a partner or vendor portal of your own that lists everything Coverbase is waiting on from one vendor.
`GET /v1/vendors?external_id=` returns the Coverbase `vendor_id` for the identifier your system holds. Match by `name` if you have not set `external_id` on your vendors yet.
`GET /v1/portals?vendor_id=&state=open`, then the same call with `state=overdue`. Or fetch without `state` and group rows by it, which also gives you the submitted and closed history.
Render each row's `display_name`, `due_at`, and `url`. Mark `overdue` rows and `paused` rows so the reader knows which ones need action now.
Poll on a schedule that suits you; the list is cheap. To react to a change as it happens instead, subscribe to `Assessment.*` events with [webhooks](/integrations/webhooks#event-catalog).
## Related
* [Vendors API](/api-reference/vendors): resolve a vendor by `external_id` or name.
* [Assessments API](/api-reference/assessments): the assessment an `assessment` request collects for.
* [Centralized supplier portal](/user-guides/centralized-supplier-portal): one sign-in page per vendor that lists every request.
* [API conventions](/conventions): pagination, timestamps, and the error envelope.
# Radar API
Source: https://docs.coverbase.com/api-reference/radar
Create radar events, and list, retrieve, and triage (dismiss) radar alerts.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
**Radar** is Coverbase's continuous third-party monitoring surface. Two object types are exposed here:
* A **radar event** (`cbrevent_...`) records something that happened to one or more vendors and groups the source data behind it (news, advisories, breach disclosures).
* A **radar alert** (`cbrdrres_...`) is one detector's verdict that a piece of source data is relevant to one vendor. Alerts are what you triage here: dismiss the noise, or escalate into a [reassessment](/api-reference/reassessments).
The dashboard rolls an event's alerts up into a **signal**: one row per event carrying your organization's status, title, and summary. Signals are not addressable through the API. Read the event for what happened, and the alerts for which detector flagged which vendor. See the Supplier Radar [key concepts](/products/supplier-radar#key-concepts).
All endpoints are org-scoped to the API key. See [API conventions](/conventions) for shared behavior, including [pagination](/conventions#pagination).
| Method | Path |
| - | - |
| `GET` | `/v1/radar/events` |
| `POST` | `/v1/radar/events` |
| `GET` | `/v1/radar/events/{event_id}` |
| `GET` | `/v1/radar/events/{event_id}/alerts` |
| `GET` | `/v1/radar/alerts` |
| `GET` | `/v1/radar/alerts/{alert_id}` |
| `POST` | `/v1/radar/alerts/{alert_id}/dismiss` |
| `POST` | `/v1/radar/alerts/{alert_id}/undismiss` |
| `GET` | `/v1/radar/detectors` |
| `GET` | `/v1/radar/sources` |
None of these honor `Idempotency-Key`.
## Create a radar event
`POST /v1/radar/events`
Returns `201 Created`. Use this to seed an event into Radar without waiting for a source feed to pick up the underlying article; useful for recording out-of-band incidents and for exercising your detectors against a known event. Supplied vendors are linked to the event as **primary-impacted**, and the event is evaluated against your detectors unless you opt out (see [detector evaluation](#detector-evaluation)).
### Request body
Short event name.
Event summary / description.
Primary impact category. Case-sensitive; one of `Infosec`, `Financial`, `Operational`, `Legal`, `Compliance`, `Reputational`, `Contractual`, `ESG`, `Corporate`, `Geopolitical & External`, `Inapplicable`, `Other`.
Additional impact categories, from the same list as `primary_impact_type`. A
value outside it is rejected with `422`. These categories decide which
category-filtered detectors can match the event.
Vendors directly impacted (`cbvndr_...`). Each is linked as primary-impacted. Vendors that cannot be resolved, or that are not yet linked to a company record, are skipped silently.
Risk domains to record on the event (`cbrdom_...`), returned on the [radar
event object](#radar-event-object). An id your org does not have is rejected
with `400 risk_domain_not_found`.
URL of the underlying article / report.
Name of the source.
When the event occurred (Unix seconds). Defaults to now when omitted.
Evaluate the event against the detectors that target each linked vendor, raising
[radar alerts](#list-radar-alerts) for the ones that fire. Default `true`. Pass
`false` to record an event without spending a model call per (detector, vendor).
### Detector evaluation
The scheduled Radar pipeline is source-driven: it evaluates what its configured
sources pull in, and never sees an event created through this endpoint. Events
posted here are therefore evaluated out of band, which happens by default. Pass
`create_alert: false` to store one without evaluating it.
Evaluation is asynchronous: the response returns as soon as the event is stored,
and alerts appear on [`GET /v1/radar/alerts`](#list-radar-alerts) once the detectors
finish, each carrying this event's `event_id`. What runs against the event:
* **Vendors.** The vendors in `vendor_ids` that resolve within your org, plus the
vendors that depend on them: a breach at a supplier is evaluated against the
customers exposed to it, the same expansion the scheduled pipeline performs, and
through the same caps. An event with no resolvable vendor is stored but never
evaluated.
* **Detectors.** Only the ones that already target each of those vendors, including
the detector's source scoping: a detector limited to specific sources sees this
event only if it includes the org's **Manually-created events** source. Detectors
with an impact-category filter are matched against the event's own
`primary_impact_type` and `secondary_impact_types`.
* **Cost.** One model call per (detector, vendor) pair, counting the vendors
reached by expansion. Pass `create_alert: false` on events you only want recorded.
Re-posting the same event is safe: each (event, vendor, detector) combination is
evaluated once, so retries do not duplicate alerts or re-notify reviewers.
To tell whether an event was evaluated, read [its alerts](#list-an-events-alerts):
`evaluation_status` separates "never evaluated", "still evaluating", and "evaluated
with nothing raised".
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/radar/events" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme data breach",
"summary": "Acme disclosed unauthorized access to a customer database.",
"primary_impact_type": "Infosec",
"vendor_ids": ["cbvndr_e448ba62882143f3ba0c140bb2e30162"],
"source_url": "https://news.example.com/acme-breach",
"source_name": "Example News",
"create_alert": true
}'
```
Returns the [radar event object](#radar-event-object).
### Radar event object
Radar event ID (`cbrevent_...`).Event name.Event summary.Primary impact category.Additional impact categories.Risk domains recorded on the event.When the event occurred (Unix seconds).`true` if archived.Unix timestamp (seconds).Unix timestamp (seconds).
## List radar events
`GET /v1/radar/events`
### Query parameters
Filter by primary impact category.
Include archived events. Default `false`.
Page size. Default `50`, range `1`-`200`.
Page offset. Default `0`.
The list envelope adds `total`, `limit`, and `offset`. See [pagination](/conventions#pagination).
## Retrieve a radar event
`GET /v1/radar/events/{event_id}`
Returns the [radar event object](#radar-event-object), or `404 radar_event_not_found`.
## List an event's alerts
`GET /v1/radar/events/{event_id}/alerts`
Returns the detector results for one event, plus the state of its evaluation. An
event that raised nothing looks the same from outside whether it was never
evaluated, is still being evaluated, or was evaluated and judged irrelevant; the
envelope's counts separate the three.
Include detector runs that scored the event without alerting. Default `false`.
Dismissal filter. Omit for both; `true` for only dismissed; `false` for only active.
Include archived results. Default `false`.
Page size. Default `50`, range `1`-`200`.
Page offset. Default `0`.
The response is the usual list envelope of [radar alert objects](#radar-alert-object)
(`items`, `total`, `limit`, `offset`) plus:
`not_requested` (the event was stored without evaluation, or no linked vendor
resolved), `pending` (evaluation was requested and no detector has reported yet),
or `completed` (at least one detector scored the event).
Detector results recorded for the event, alerting or not, ignoring your filters.How many of those results raised an alert.
Returns `404 radar_event_not_found` for an unknown event.
## List radar alerts
`GET /v1/radar/alerts`
### Query parameters
Filter to alerts on a vendor (`cbvndr_...`).
Filter by severity, one of `informational`, `low`, `medium`, `high`. Repeat the
param for multiple values: `severity=high&severity=medium`.
Dismissal filter. Omit to hide dismissed alerts (default); `true` for only dismissed; `false` for only active.
Include archived alerts. Default `false`.
Page size. Default `50`, range `1`-`200`.
Page offset. Default `0`.
### Example response
```json theme={null}
{
"items": [
{
"id": "cbrdrres_9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"detector_id": "cbrdrdet_2d5e8f1a4b7c0d3e6f9a2b5c8d1e4f7a",
"source_id": "cbradarsrc_1111111111111111111111111111aaaa",
"data_id": "cbradardata_2222222222222222222222222222bbbb",
"event_id": "cbrevent_3333333333333333333333333333cccc",
"summary": "Acme disclosed a data breach affecting customer records.",
"severity": "high",
"confidence": "high",
"should_alert": true,
"is_dismissed": false,
"dismiss_reason": null,
"dismissed_at": null,
"is_archived": false,
"created_at": 1746576000,
"updated_at": 1746576400
}
],
"total": 1,
"limit": 50,
"offset": 0
}
```
### Radar alert object
Radar alert ID (`cbrdrres_...`).Vendor the alert is on (`cbvndr_...`).Detector that produced the alert (`cbrdrdet_...`).Radar source (`cbradarsrc_...`).Underlying source data item (`cbradardata_...`).Radar event the alert's data belongs to (`cbrevent_...`), if any.Alert summary.Severity (`informational`, `low`, `medium`, `high`).Detector confidence (`low`, `medium`, `high`).`true` for a triggered alert.`true` if dismissed.Reason recorded at dismissal, if any.When dismissed (Unix seconds).`true` if archived.Unix timestamp (seconds).Unix timestamp (seconds).
## Retrieve a radar alert
`GET /v1/radar/alerts/{alert_id}`
Returns the [radar alert object](#radar-alert-object), or `404 alert_not_found`.
## Dismiss a radar alert
`POST /v1/radar/alerts/{alert_id}/dismiss`
Marks an alert as dismissed (triaged as not actionable). Returns the refreshed [radar alert object](#radar-alert-object).
### Request body
Optional dismissal reason. Surfaced in the UI and, when `suppress_similar` is set, fed into the detector's learning context.
When `true`, the alert is also recorded as a negative example on its detector so future runs suppress similar alerts. Default `false`.
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/radar/alerts/cbrdrres_9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d/dismiss" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "reason": "Duplicate of an existing event", "suppress_similar": true }'
```
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "alert_not_found", "message": "Radar alert not found."}}` | Not found, or not in the API key's org. |
Dismissing an already-dismissed alert is a no-op that returns `200` with the alert; a
`reason` supplied on the repeat call replaces the stored one.
## Restore a dismissed alert
`POST /v1/radar/alerts/{alert_id}/undismiss`
Restores a dismissed alert to the active list. Returns the refreshed [radar alert object](#radar-alert-object), or `404 alert_not_found`.
## List detectors
`GET /v1/radar/detectors`
Lists your organization's detectors: what an event can be scored against. Filter
with `enabled` (boolean) and `include_archived` (default `false`); pages with
`limit` (default `50`, range `1`-`200`) and `offset`.
Each detector carries `id` (`cbrdrdet_...`), `name`, `description`, `enabled`,
`category_filters` (the impact categories it matches), `source_ids` (the sources it
is limited to), `applies_to_all_vendors`, `included_vendor_ids`,
`excluded_vendor_ids`, `severity_threshold`, `is_archived`, `created_at`, and
`updated_at`.
## List sources
`GET /v1/radar/sources`
Lists your organization's Radar sources. Pages with `limit` (default `50`, range
`1`-`200`) and `offset`; pass `include_archived=true` to include archived sources.
Each source carries `id` (`cbradarsrc_...`), `name`, `is_archived`, `created_at`, and
`is_manual_events`, which is `true` on the source that events created through this
API land on. Add that source to a source-limited detector if you want it to evaluate
API events.
## Related
* [Reassessments API](/api-reference/reassessments): escalate an alert/event into a batch of vendor reassessments.
* [Webhooks](/integrations/webhooks#event-catalog): subscribe to `RadarEvent.*` and `RadarDetectorResult.*` events.
# Reassessments API
Source: https://docs.coverbase.com/api-reference/reassessments
Create reassessments from radar events, curate the vendor set, and run them.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A **reassessment** (`cbrsm_...`) is a draft batch of assessments to run against a set of vendors, typically prompted by a [radar event or alert](/api-reference/radar). It lets you curate the vendor set and choose an assessment plan, then run it, without ever opening a case.
A reassessment moves through four statuses:
| Status | Meaning |
| - | - |
| `draft` | Newly created; awaiting review and vendor curation. |
| `confirmed` | Vendor set confirmed; ready to run. |
| `run` | Assessments have been created from the linked plan. **Terminal.** |
| `dismissed` | Closed without running. **Terminal.** |
A reassessment in a terminal status (`run` or `dismissed`) is immutable.
All endpoints are org-scoped to the API key. See [API conventions](/conventions) for shared behavior.
| Method | Path |
| - | - |
| `GET` | `/v1/reassessments` |
| `POST` | `/v1/reassessments` |
| `GET` | `/v1/reassessments/{reassessment_id}` |
| `PATCH` | `/v1/reassessments/{reassessment_id}` |
| `POST` | `/v1/reassessments/{reassessment_id}/vendors` |
| `POST` | `/v1/reassessments/{reassessment_id}/vendor_inclusion` |
| `POST` | `/v1/reassessments/{reassessment_id}/confirm` |
| `POST` | `/v1/reassessments/{reassessment_id}/dismiss` |
| `POST` | `/v1/reassessments/{reassessment_id}/run` |
None of these honor `Idempotency-Key`.
## Create a reassessment
`POST /v1/reassessments`
Returns `201 Created`. Creates a `draft` reassessment from a radar event with an initial vendor set. The assessment plan is optional up front; set it later with a `PATCH` before running.
### Request body
The radar event providing context for the reassessment (`cbrevent_...`).
Vendors to include (`cbvndr_...`). At least one; all must belong to the API key's org.
Assessment plan to run (`cbaspl_...`). Optional; set later before running.
Reassessment title.
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/reassessments" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"radar_event_id": "cbrevent_3333333333333333333333333333cccc",
"vendor_ids": ["cbvndr_e448ba62882143f3ba0c140bb2e30162"],
"title": "Reassess Acme after breach"
}'
```
Returns the [reassessment object](#reassessment-object).
### Reassessment object
Reassessment ID (`cbrsm_...`).`draft`, `confirmed`, `run`, or `dismissed`.Title.Linked assessment plan (`cbaspl_...`).Source radar event (`cbrevent_...`).Radar alerts that drove the reassessment.Per-vendor entries; see below.Unix timestamp (seconds).Unix timestamp (seconds).
Each `vendors[]` entry:
Vendor (`cbvndr_...`).How the vendor joined: `matched` (added at creation) or `manual` (added during review).Whether the vendor is in the run set.Assessment created for this vendor once the reassessment is run.
## List reassessments
`GET /v1/reassessments`
### Query parameters
Filter by status (`draft`, `confirmed`, `run`, `dismissed`).
Returns an `items` array of [reassessment objects](#reassessment-object), newest first, with `total`, `limit`, and `offset`. Every match is returned in one page.
## Retrieve a reassessment
`GET /v1/reassessments/{reassessment_id}`
Returns the [reassessment object](#reassessment-object), or `404 reassessment_not_found`.
## Update a reassessment
`PATCH /v1/reassessments/{reassessment_id}`
Update editable metadata. Only included fields change. Rejected with `422 reassessment_immutable` once the reassessment is `run` or `dismissed`.
### Request body
New title.Assessment plan to run (`cbaspl_...`).Re-link to a different radar event (`cbrevent_...`).
## Curate the vendor set
`POST /v1/reassessments/{reassessment_id}/vendors`
Add manually-selected vendors. Body: `{ "vendor_ids": ["cbvndr_..."] }` (at least one).
`POST /v1/reassessments/{reassessment_id}/vendor_inclusion`
Opt a single vendor in or out of the run set. Body: `{ "vendor_id": "cbvndr_...", "included": false }`.
Both return the refreshed [reassessment object](#reassessment-object).
## Confirm, dismiss, run
`POST /v1/reassessments/{reassessment_id}/confirm`
Move a `draft` reassessment to `confirmed` (vendor set locked in, ready to run).
`POST /v1/reassessments/{reassessment_id}/dismiss`
Close a reassessment without running it (`dismissed`).
`POST /v1/reassessments/{reassessment_id}/run`
Create an assessment from the linked plan for each **included** vendor that does not have one yet, then mark the reassessment `run`. It can run from `draft` or `confirmed`. Requires `assessment_plan_id` to be set first; otherwise `400 missing_assessment_plan`. This **never** creates a case.
When the reassessment is linked to a radar event, running it also marks that event's signal as triaged and applies the risk impact of the linked alerts (or, if none were recorded, the event's active alerts) to the vendors.
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/reassessments/cbrsm_1234/run" \
-H "Authorization: Bearer ak_live_xxx"
```
All three return the refreshed [reassessment object](#reassessment-object).
### Error responses
| Status | Body | When |
| - | - | - |
| 400 | `{"detail": {"code": "missing_assessment_plan", ...}}` | `run` called before an assessment plan is set. |
| 404 | `{"detail": {"code": "reassessment_not_found", ...}}` | Not found / not in the API key's org. |
| 422 | `{"detail": {"code": "reassessment_immutable", ...}}` | Editing or running a `run`/`dismissed` reassessment. |
| 422 | `{"detail": {"code": "invalid_reassessment", ...}}` | The request was rejected, for example a vendor or plan that does not resolve. |
## Related
* [Radar API](/api-reference/radar): the events and alerts that prompt reassessments.
* [Webhooks](/integrations/webhooks#event-catalog): subscribe to `Reassessment.*` events.
# Supplier Profile API
Source: https://docs.coverbase.com/api-reference/supplier-profile
Read and write a vendor's bank accounts, sites, tax registrations and legal entity assignments, send update requests, and follow every change to them.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A vendor's **supplier profile** is what your organization holds about how to pay and reach that supplier: its bank accounts, its sites (addresses and other locations), its tax and company registrations, its diversity records, and the legal entities of yours it is assigned to. In the dashboard these are the records on the vendor's **Know-Your-Vendor** tab; see [Supplier information](/user-guides/supplier-information). This API is how a finance system or middleware reads those records, writes them, and keeps up with changes to them.
The profile is not an object with an ID of its own. Every record in it belongs to a vendor (`cbvndr_...`) and lives under `/v1/vendors/{vendor_id}/`. The one exception is the list of your own legal entities, at `/v1/legal_entities`.
Know Your Vendor is not on for every organization. While it is off, every endpoint on this page returns `404` with the code `not_enabled`. If you get that response, ask your Coverbase account team to turn it on.
All endpoints are org-scoped to the API key. See [API conventions](/conventions) for authentication, IDs, timestamps and the error envelope. None of them honor `Idempotency-Key`. A tax registration write is an upsert and safe to repeat; the other writes are not, so list the records before you retry one that timed out.
No endpoint needs a scope: a standard integration key can call all of them. The scopes in the last column change what a call returns or does; see [masking and scopes](#masking-and-scopes).
| Method | Path | Scope that changes the result |
| - | - | - |
| `GET` | `/v1/vendors/{vendor_id}/bank_accounts` | `banking:read` |
| `POST` | `/v1/vendors/{vendor_id}/bank_accounts` | `review:sensitive_changes` |
| `PATCH` | `/v1/vendors/{vendor_id}/bank_accounts/{bank_account_id}` | `review:sensitive_changes` |
| `POST` | `/v1/vendors/{vendor_id}/bank_accounts/{bank_account_id}/retire` | - |
| `GET` | `/v1/vendors/{vendor_id}/sites` | - |
| `POST` | `/v1/vendors/{vendor_id}/sites` | - |
| `PATCH` | `/v1/vendors/{vendor_id}/sites/{site_id}` | - |
| `DELETE` | `/v1/vendors/{vendor_id}/sites/{site_id}` | - |
| `GET` | `/v1/vendors/{vendor_id}/tax_registrations` | `banking:read` |
| `POST` | `/v1/vendors/{vendor_id}/tax_registrations` | - |
| `GET` | `/v1/vendors/{vendor_id}/diversity_records` | - |
| `GET` | `/v1/legal_entities` | - |
| `GET` | `/v1/vendors/{vendor_id}/legal_entity_assignments` | - |
| `POST` | `/v1/vendors/{vendor_id}/legal_entity_assignments` | - |
| `GET` | `/v1/vendors/{vendor_id}/update_requests` | - |
| `POST` | `/v1/vendors/{vendor_id}/update_requests` | - |
| `GET` | `/v1/vendors/changes` | - |
A successful bank write is not a changed bank account. By default a new or changed account waits for a reviewer, and the call answers `202 Accepted` with a review ID. Update your finance system only when the account goes live: the `VendorBankAccount` webhook fires on approval, and the change feed records an `approved` event.
## How the profile fits together
### What a profile holds
| Record | ID prefix | Through this API |
| - | - | - |
| Bank account | `cbvba_` | List, add, update, retire |
| Site | `cbsite_` | List, add, update, delete |
| Tax registration | `cbtaxreg_` | List, add or update |
| Diversity record | `cbdiv_` | List only |
| Legal entity assignment | `cblea_` | List, add |
| Update request | `cbupdreq_` | List, send |
| Change event | `cbpce_` | List (Coverbase writes them) |
Two more IDs appear in responses: a **legal entity** (`cble_...`) is one of your own contracting entities, set up under **Configuration → Legal entities**, and a **bank change review** (`cbbarev_...`) is a bank write waiting for a reviewer.
Sites are also the vendor's locations: the sites you read and write here are the ones on the vendor's **Locations** card and on the [Risk geography map](/user-guides/risk-geography-map).
### Who changes what
| Who | How | What they can change |
| - | - | - |
| The supplier | A **Know-Your-Vendor** questionnaire, or the **Profile** page of the [centralized supplier portal](/user-guides/centralized-supplier-portal) when you have turned that section on | Bank accounts, sites, tax registrations and diversity records: in a questionnaire, through the questions you ask; on the portal, within the sections you open |
| Your staff | The vendor's **Know-Your-Vendor** tab, with the supplier banking and supplier profile [permissions](/user-guides/supplier-information#who-can-see-and-do-what) | Every section, and they decide queued changes |
| Your integration | This API | Bank accounts, sites, tax registrations and legal entity assignments, plus update requests. Not diversity records, not approvals, and not your list of legal entities |
| Coverbase | Automatically, on save or in the background | Registry results on tax registrations, map coordinates on sites, the tax region of each site and the payment method of each bank account |
Changes to these records, whoever makes them, are appended to the vendor's change history. The same history drives the **Know-Your-Vendor** tab, the [supplier profile webhooks](/integrations/webhooks#supplier-profile-events) and the [change feed](#the-change-feed). A change made with an API key is recorded with `actor_type` `api` and `actor_label` `API`, and the records it creates carry `source` `api`.
### What waits for approval
| Change | Waits when | Until then |
| - | - | - |
| A new bank account, or a change to an account's details (its `values`) | **Bank changes need a reviewer** is on. It is on by default. | The live account is untouched, the call answers `202`, and no webhook fires. |
| A legal entity assignment | **Legal entity assignments need approval** is on. It is off by default. | The assignment has status `requested` and no webhook fires. |
| Everything else | Never | Saved immediately if the country's rules pass. |
Both settings are in **Configuration → Know Your Vendor Settings**; see [Configuring it for your organization](/user-guides/supplier-information#configuring-it-for-your-organization). A reviewer decides a queued bank change on the vendor's **Know-Your-Vendor** tab or on the **Vendor changes** page. The API has no call to approve or reject one. Retiring a bank account never waits.
### Masking and scopes
An API key authenticates as a service account. With a standard key, an account number, IBAN or tax identifier comes back as its last four characters (`****6789`), a bank account's other fields are not returned apart from its SWIFT/BIC, and every bank write queues for review. An admin can grant a key two scopes that change this, under **Admin scopes (optional)** on the **API keys** page:
| Scope | Label on the **API keys** page | Effect on this API |
| - | - | - |
| `banking:read` | **Read full bank and tax identifiers** | [List bank accounts](#list-bank-accounts) adds `values`, every field in full, and [list tax registrations](#list-tax-registrations) adds `value`. Nothing else unmasks: write responses, change events and webhooks stay masked. |
| `review:sensitive_changes` | **Write bank details without review** | A bank write from this key skips the review queue and takes effect at once. It is still recorded in the change history, and its webhook fires immediately. The key cannot approve or reject changes that others queued: no endpoint does that, and a reviewer decides them in the dashboard. |
Grant either only to a key that needs it. See [API key scopes](/conventions#api-key-scopes) and [role-based masking](/security/data-protection#role-based-masking). A dashboard session token also works on these endpoints, but it never unmasks values and never skips review.
### Country rules and validation
Bank accounts, sites and tax registrations are checked against the rules for their country, which [Supplier countries](/user-guides/supplier-countries/overview) lists field by field. Values are normalized first, and the normalized value is what Coverbase stores: spaces come out of an IBAN, and a United Kingdom sort code shorter than six digits is padded with leading zeros.
* An **error** rejects the write with `422` and the code `validation_failed`, and nothing is saved.
* A **warning** lets the write through. The warning is kept on the record's `validation_results`.
A country Coverbase has no rules for is not refused: the values are stored unchecked, and `config_version` reads `unconfigured`.
Every record that was validated carries the outcome in `validation_results`:
```json theme={null}
{
"status": "passed_with_warnings",
"results": [
{
"field": "po_emails",
"rule_id": "email.missing",
"level": "warning",
"message": "A PO email address is how the finance system reaches this supplier. Add at least one address.",
"params": { "label": "A PO email address" }
}
],
"config_version": "2026.09.1"
}
```
| Field | Notes |
| - | - |
| `status` | `passed`, `passed_with_warnings` or `failed`. A saved record is never `failed`. |
| `results[].field` | The field key the result is about, such as `branch_code` or `postal_code`. |
| `results[].rule_id` | A stable rule identifier, such as `checksum.failed`, `field.required` or `iban.mod97`. Branch on this, not on `message`. |
| `results[].level` | `error` or `warning`. |
| `results[].message` | A sentence you can show a person. |
| `results[].params` | The values the message was built from, such as the field `label`. |
| `config_version` | The version of the country rules that ran, or `unconfigured`. |
A write that fails validation returns the same results in the error body. It uses an `error` key rather than the usual `code`:
```json theme={null}
{
"detail": {
"error": "validation_failed",
"results": [
{
"field": "branch_code",
"rule_id": "checksum.failed",
"level": "error",
"message": "Routing Transit Number failed its check-digit validation. Check for a typo.",
"params": { "label": "Routing Transit Number", "field": "branch_code", "algorithm": "us_aba_mod10" }
}
],
"config_version": "2026.09.1"
},
"request_id": "41ff4305-740d-4181-bed9-1fbe21bd69ab"
}
```
### Errors every endpoint can return
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "not_enabled", "message": "Know Your Vendor is not enabled for this organization."}}` | Know Your Vendor is off for your organization. It is checked before the vendor. |
| 404 | `{"detail": {"code": "vendor_not_found", "message": "Vendor not found."}}` | `vendor_id` does not exist or is not in the API key's org. |
| 404 | `{"detail": "Not Found"}` | A bank account or site that does not exist or belongs to a different vendor, a site that was deleted, or, on an update, a retired bank account. |
| 422 | Standard validation error | The body failed schema validation. Request bodies are strict: a field this page does not list is rejected. |
Authentication failures and the IP allowlist behave as on every public endpoint; see [API conventions](/conventions#errors). Calls made with an `ak_` key are recorded in the [public API audit log](/conventions#public-api-audit-log).
## Bank accounts
### The bank account object
Bank account ID (`cbvba_...`).The vendor the account belongs to.Two-letter country code of the bank that holds the account. `null` on an account recorded before country validation existed.Three-letter currency code, upper case.A label for the account, such as `Operating account`. It is not the account holder's name.The last four characters of the account number, as `****6789`.The last four characters of the IBAN.The SWIFT/BIC in full. It identifies the bank, not the account, so it is never masked.Whether this is the vendor's primary account. A vendor has at most one.`active`, or `retired` on the response to a retire call.`passed`, `passed_with_warnings`, or `not_validated` for an account recorded before country validation existed.The [validation outcome](#country-rules-and-validation).The country rules version the account was validated against.`domestic` or `wire`, derived when the account was saved. It is `wire` when the bank's country is not one your assigned legal entities pay from, and `null` when the vendor had no active [legal entity assignment](#legal-entities-and-assignments) with a country at the time.A vendor document (`cbvdoc_...`) attached as proof the account belongs to the supplier.Where the account came from: `questionnaire`, `portal`, `api`, `internal` or `migration`.Unix timestamp (seconds).Unix timestamp (seconds).Every field of the account in full, keyed by [field key](#bank-account-values). A field the account does not use is an empty string. Present only on [list bank accounts](#list-bank-accounts) for a key with `banking:read`; `null` everywhere else.
### List bank accounts
`GET /v1/vendors/{vendor_id}/bank_accounts`
Returns the vendor's active bank accounts as a plain array, primary first, then oldest first. Retired accounts and changes still waiting for review are not included. The list is not paginated.
**Auth:** any `ak_` key. With `banking:read`, each account also carries `values`.
#### Path parameters
The vendor ID (`cbvndr_...`).
#### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/bank_accounts" \
-H "Authorization: Bearer ak_live_xxx"
```
#### Example response
`200 OK`, for a key with `banking:read`. Without the scope, `values` is `null`.
```json theme={null}
[
{
"id": "cbvba_472ae9b13b64f2ad9217d12be653dbb2",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"bank_country": "US",
"currency": "USD",
"bank_account_name": "Operating account",
"account_number_masked": "****6789",
"iban_masked": null,
"swift_bic": null,
"is_primary": true,
"status": "active",
"validation_status": "passed",
"validation_results": { "status": "passed", "results": [], "config_version": "2026.09.1" },
"config_version": "2026.09.1",
"payment_method": "domestic",
"statement_document_id": null,
"source": "api",
"created_at": 1790467305,
"updated_at": 1790467305,
"values": {
"account_number": "000123456789",
"account_type": "checking",
"bank_code": "",
"bank_name": "First Example Bank",
"branch_code": "076401251",
"check_digit": "",
"iban": "",
"swift_bic": ""
}
}
]
```
### Add a bank account
`POST /v1/vendors/{vendor_id}/bank_accounts`
Validates the account against its country's rules, then either queues it for a reviewer or saves it.
**Auth:** any `ak_` key. A key with `review:sensitive_changes` skips the review queue.
#### Path parameters
The vendor ID (`cbvndr_...`).
#### Request body
Two-letter country code of the bank that holds the account, which is not always the supplier's own country. It decides which fields are asked for and which rules apply.
The account's fields, keyed by [field key](#bank-account-values), for example `{"branch_code": "076401251", "account_number": "000123456789", "account_type": "checking"}`. Keys the country does not define are dropped. Values can be `null`.
Three-letter currency code. `BRL` is refused when the supplier's own address is outside Brazil, judged by its primary site (or its first site, if none is primary). A supplier with no sites is not checked.
A label for the account. On a write that is queued for review, it takes effect when the change is approved.
`true` makes this the vendor's primary account and demotes the current one. Omit it or send `false` for a secondary account.
A document already uploaded for this vendor with the [Documents API](/api-reference/documents) (`cbvdoc_...`), such as a bank statement showing the account belongs to the supplier. A document of another vendor is refused with `422` and the code `invalid_document`. On a write that is queued for review, it is attached when the change is approved.
#### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/bank_accounts" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"bank_country": "US",
"currency": "USD",
"is_primary": true,
"values": {
"bank_name": "First Example Bank",
"branch_code": "076401251",
"account_number": "000123456789",
"account_type": "checking"
}
}'
```
#### Example responses
`202 Accepted`: the account is queued for review. This is the default outcome.
```json theme={null}
{
"status": "pending_review",
"review_id": "cbbarev_6f1085b71efca801572074863961a938",
"message": "Bank details are held for review before taking effect."
}
```
Coverbase tells the people named in **Notify these people**, or, when nobody is named, the vendor's relationship owners (its risk analysts if it has none). The change feed records a `submitted` event whose `entity_id` is the `review_id`. See [following a queued bank change](#following-a-queued-bank-change).
`201 Created`: the account is saved, because your organization has turned off **Bank changes need a reviewer** or the key carries `review:sensitive_changes`. The body is the [bank account object](#the-bank-account-object), with `values` always `null`. The `VendorBankAccount.Created` webhook fires.
#### Error responses
| Status | Body | When |
| - | - | - |
| 409 | `{"detail": {"code": "bank_account_limit", "message": "This supplier already has 10 bank accounts."}}` | The vendor's active accounts, together with its new accounts waiting for review, already reach the most your organization allows (**Bank accounts per supplier**, 10 by default). Retire one, or wait for a queued one to be decided. |
| 422 | `{"detail": {"code": "invalid_document", "message": "statement_document_id must be one of this supplier's documents.", "field": "statement_document_id"}}` | `statement_document_id` is not a document of this vendor. |
| 422 | `{"detail": {"error": "validation_failed", ...}}` | An error-level country rule failed. See [country rules and validation](#country-rules-and-validation). |
### Update a bank account
`PATCH /v1/vendors/{vendor_id}/bank_accounts/{bank_account_id}`
Replaces an account's details. It takes the same body as [add a bank account](#add-a-bank-account), and `bank_country` and `values` are required. `values` replaces the whole set, so send every field the account should keep, not only the one that changed.
**Auth:** any `ak_` key. A key with `review:sensitive_changes` skips the review queue.
The outcomes match the add call: `202 Accepted` with a `review_id` while the change waits for a reviewer, or `200 OK` with the updated [bank account object](#the-bank-account-object) when it is applied at once. The live account keeps serving its current details until a reviewer approves.
A PATCH whose `values` match what the account already holds is not a bank change. Its `currency`, `bank_account_name`, `is_primary` and `statement_document_id` are applied at once, without review, and when one of them changes, the change feed records an `updated` event and `VendorBankAccount.Updated` fires. Sending back exactly what is stored records nothing. Any difference in `values`, including a new `swift_bic`, `bank_name` or `account_type` on the same account number, is a bank change and waits for review like any other.
#### Path parameters
The vendor ID (`cbvndr_...`).
The bank account ID (`cbvba_...`). It must belong to `vendor_id`.
#### Example request
```bash cURL theme={null}
curl -X PATCH "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/bank_accounts/cbvba_472ae9b13b64f2ad9217d12be653dbb2" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"bank_country": "US",
"currency": "USD",
"values": {
"bank_name": "First Example Bank",
"branch_code": "076401251",
"account_number": "000987654321",
"account_type": "checking"
}
}'
```
#### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": "Not Found"}` | The account does not exist, was retired, or belongs to a different vendor. |
| 422 | `{"detail": {"code": "invalid_document", ...}}` | `statement_document_id` is not a document of this vendor. |
| 422 | `{"detail": {"error": "validation_failed", ...}}` | An error-level country rule failed. |
### Retire a bank account
`POST /v1/vendors/{vendor_id}/bank_accounts/{bank_account_id}/retire`
Retires an account at once; retiring never waits for review. The account stops being primary, drops out of [list bank accounts](#list-bank-accounts), and the `VendorBankAccount.Retired` webhook fires. The call takes no body and returns `200 OK` with the [bank account object](#the-bank-account-object), `status` set to `retired`. Calling it again on a retired account returns the account unchanged and records nothing, so a retry is safe.
**Auth:** any `ak_` key.
#### Path parameters
The vendor ID (`cbvndr_...`).
The bank account ID (`cbvba_...`). It must belong to `vendor_id`.
#### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/bank_accounts/cbvba_472ae9b13b64f2ad9217d12be653dbb2/retire" \
-H "Authorization: Bearer ak_live_xxx"
```
#### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": "Not Found"}` | The account does not exist or belongs to a different vendor. |
### Following a queued bank change
The review ID is the only handle a queued change has, and the API has no endpoint that reads a review. Follow it through the [change feed](#the-change-feed):
* A `rejected` event on `bank_account` whose `entity_id` is your `review_id` means the reviewer turned it down, and its `snapshot` carries the `rejection_reason`. The live account never changed.
* An `approved` event on `bank_account` means it went live. Its `entity_id` is the bank account ID, not the review ID: for a change to an existing account it is the account you patched, and for a new account it is the account the approval created, which then appears in [list bank accounts](#list-bank-accounts). Nothing in the event names the review, so match a new account to your request by vendor, `bank_country` and `account_number_masked`.
## Sites
A site is one place the supplier operates, at whatever precision is known: a full street address, a city, or a country on its own. Only the country is required. Sites carry the addresses your finance system pays and orders against, and they are the vendor's locations on the [Risk geography map](/user-guides/risk-geography-map).
### The site object
Site ID (`cbsite_...`).The vendor the site belongs to.The service this location belongs to, when someone scoped it to one on the vendor page. The API does not set it.First address line.Second address line.Third address line.Fourth address line.City or town.State, province or region, as given: an ISO 3166-2 code such as `NY`, or free text.County, where the country files one separately from the state.Postal code.Two-letter country code. Always present.A short label for the location, such as `Global HQ`.What happens at this location, in your words. An empty string when there is none.`ordering`, `billing`, `service_delivery`, `hq` or `other`. A label set on the vendor page; nothing derives it.What the address is for in your finance system: `primary` or `remittance`. An address is a registration address by carrying a tax registration, not by its purpose.Your finance system's code for this address.Your finance system's identifier for this address as a remit-to site.Derived from the address unless the API sets it: the country code, or the country and subdivision (`US-NY`) in the United States, Canada, India and Brazil. The supplier is never asked for it.Where purchase orders for this address are emailed.Where remittance advice for this address is emailed.Whether this is the vendor's primary site. A vendor has at most one.Filled in by Coverbase after the site is saved, from the address. `null` until then, and always `null` for a country-only site.As `latitude`.`active`. Deleted sites are not returned.Where the site came from: `questionnaire`, `portal`, `api`, `internal` or `migration`.The [validation outcome](#country-rules-and-validation). Postal-code format problems, over-long address lines and a missing PO email address are warnings, never errors.Unix timestamp (seconds).Unix timestamp (seconds).
### List sites
`GET /v1/vendors/{vendor_id}/sites`
Returns the vendor's sites as a plain array, primary first, then oldest first. The list is not paginated.
**Auth:** any `ak_` key.
#### Path parameters
The vendor ID (`cbvndr_...`).
#### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/sites" \
-H "Authorization: Bearer ak_live_xxx"
```
#### Example response
`200 OK`:
```json theme={null}
[
{
"id": "cbsite_f4f317ab5908a1a38899c0559f3ef3c1",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"service_id": null,
"address_line1": "45 Harbour Road",
"address_line2": null,
"address_line3": null,
"address_line4": null,
"city": "New York",
"state_province": "NY",
"county": null,
"postal_code": "10001",
"country_code": "US",
"site_name": "Global HQ",
"description": "",
"site_context": null,
"address_purpose": "primary",
"location_code": "NY-HQ-01",
"csp_remit_to_id": null,
"tax_region": "US-NY",
"po_emails": [],
"remittance_emails": [],
"is_primary": true,
"latitude": 40.7128,
"longitude": -73.956,
"status": "active",
"source": "api",
"validation_results": {
"status": "passed_with_warnings",
"results": [
{
"field": "po_emails",
"rule_id": "email.missing",
"level": "warning",
"message": "A PO email address is how the finance system reaches this supplier. Add at least one address.",
"params": { "label": "A PO email address" }
}
],
"config_version": "2026.09.1"
},
"created_at": 1790467305,
"updated_at": 1790467305
},
{
"id": "cbsite_545527c53afc0a5f3ac414241da92cc6",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"service_id": null,
"address_line1": null,
"address_line2": null,
"address_line3": null,
"address_line4": null,
"city": null,
"state_province": null,
"county": null,
"postal_code": null,
"country_code": "BR",
"site_name": "São Paulo office",
"description": "Brazil operations / data processing",
"site_context": null,
"address_purpose": null,
"location_code": null,
"csp_remit_to_id": null,
"tax_region": "BR",
"po_emails": [],
"remittance_emails": [],
"is_primary": false,
"latitude": null,
"longitude": null,
"status": "active",
"source": "internal",
"validation_results": {},
"created_at": 1790380800,
"updated_at": 1790380800
}
]
```
### Add a site
`POST /v1/vendors/{vendor_id}/sites`
Adds a site and returns `201 Created` with the [site object](#the-site-object). The `SupplierSite.Created` webhook fires.
**Auth:** any `ak_` key.
#### Path parameters
The vendor ID (`cbvndr_...`).
#### Request body
Two-letter country code. A site with only a country is a complete answer.
Up to 255 characters. So are `address_line2`, `address_line3` and `address_line4`.Up to 120 characters.Up to 120 characters. Send the ISO 3166-2 subdivision code (`NY` or `US-NY`) where you have it: in the United States, Canada, India and Brazil the tax region is built from it, and a name such as `New York` gives the country-level region.Up to 120 characters.Up to 32 characters. Checked against the country's format, as a warning only.Up to 120 characters.Up to 500 characters.`ordering`, `billing`, `service_delivery`, `hq` or `other`.`primary` or `remittance`.Up to 60 characters.Up to 60 characters.Up to 60 characters. Your finance system's own tax region for this address. Omit it and Coverbase derives one from the address.Up to 20 addresses where purchase orders for this address are emailed. A malformed address is refused with `422`. A primary site with an address line and no PO email saves with an `email.missing` warning, except in China, where no PO email is asked for.Up to 20 addresses where remittance advice for this address is emailed. A site whose `address_purpose` is `remittance` and has none saves with an `email.missing` warning.`true` makes this the vendor's primary site and demotes the current one.
#### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/sites" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"country_code": "US",
"address_line1": "45 Harbour Road",
"city": "New York",
"state_province": "NY",
"postal_code": "10001",
"site_name": "Global HQ",
"address_purpose": "primary",
"location_code": "NY-HQ-01",
"is_primary": true
}'
```
The response is the new [site object](#the-site-object), like the first site in the [list example](#list-sites) with `latitude` and `longitude` still `null`.
#### Error responses
| Status | Body | When |
| - | - | - |
| 409 | `{"detail": {"code": "site_limit", "message": "This supplier already has 25 sites."}}` | The vendor already holds the most sites your organization allows (**Sites per supplier**, 25 by default). |
| 422 | `{"detail": {"error": "validation_failed", ...}}` | The site breaks an error-level rule: a PO box as the primary address in Australia (`address.po_box`), or a malformed email address (`email.invalid`). Nothing is saved. |
### Update a site
`PATCH /v1/vendors/{vendor_id}/sites/{site_id}`
Takes the same body as [add a site](#add-a-site) and returns `200 OK` with the updated [site object](#the-site-object). The `SupplierSite.Updated` webhook fires.
**Auth:** any `ak_` key.
Treat it as a replacement of the address rather than a partial update:
* `country_code` is required.
* Omitting an address line, `city`, `state_province`, `county`, `postal_code`, `location_code`, `csp_remit_to_id` or `description` clears it. Send every value you want to keep.
* Omitting `site_name`, `site_context` or `address_purpose` keeps the stored value. An empty `site_name` clears it; the other two cannot be cleared here.
* Omitting `po_emails` or `remittance_emails` keeps the stored list. Send `[]` to clear one.
* Omitting `tax_region` derives it from the address again.
* `is_primary: true` makes the site primary. `false` does not demote it; mark another site primary instead.
* Changing the address (other than `address_line2`) clears `latitude` and `longitude` until Coverbase places the new one.
#### Path parameters
The vendor ID (`cbvndr_...`).
The site ID (`cbsite_...`). It must belong to `vendor_id`.
#### Example request
```bash cURL theme={null}
curl -X PATCH "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/sites/cbsite_f4f317ab5908a1a38899c0559f3ef3c1" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"country_code": "US",
"address_line1": "200 Park Avenue",
"address_line2": "Floor 12",
"city": "New York",
"state_province": "NY",
"postal_code": "10166",
"location_code": "NY-HQ-01"
}'
```
#### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": "Not Found"}` | The site does not exist, was deleted, or belongs to a different vendor. |
| 422 | `{"detail": {"error": "validation_failed", ...}}` | The same rules as [add a site](#add-a-site). A primary site is checked against the email lists it will hold after the update. |
### Delete a site
`DELETE /v1/vendors/{vendor_id}/sites/{site_id}`
Removes the site and returns `204 No Content`. It no longer appears in [list sites](#list-sites), on the vendor's **Locations** card or on the map. The change history keeps the record of it, and the `SupplierSite.Deleted` webhook fires.
**Auth:** any `ak_` key.
#### Path parameters
The vendor ID (`cbvndr_...`).
The site ID (`cbsite_...`). It must belong to `vendor_id`.
#### Example request
```bash cURL theme={null}
curl -X DELETE "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/sites/cbsite_545527c53afc0a5f3ac414241da92cc6" \
-H "Authorization: Bearer ak_live_xxx"
```
#### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": "Not Found"}` | The site does not exist, was already deleted, or belongs to a different vendor. |
## Tax registrations
A tax registration is one tax or company identifier the supplier holds in one country, such as a US EIN or a UK VAT number, or a declared exemption in place of one. A registration can belong to the supplier as a whole or to one of its sites.
After a registration is saved, Coverbase checks it against the public register for that country where one exists, in the background. The check never blocks a write; it updates `registry_status` when it completes.
### The tax registration object
Tax registration ID (`cbtaxreg_...`).The vendor the registration belongs to.Two-letter country code.Which identifier this is, as a [tax ID type key](#tax-id-types) such as `ein` or `vat`.The last four characters of the identifier. `null` for an exemption.How far verification got: `format`, `checksum` (its check digits are valid) or `registry` (the public register confirmed it). The schema also defines `document`, which nothing sets.`passed`, `passed_with_warnings`, or `not_validated` for an exemption.`pending`, `verified`, `not_found` or `unavailable`. `unavailable` means the register could not be reached and says nothing about the supplier. `null` when the country has no register Coverbase checks.The register that answered.Unix timestamp (seconds) of the last register check.The site the registration belongs to.Whether this records an exemption rather than a number.Why the supplier is exempt.A vendor document (`cbvdoc_...`), such as the registration certificate.The [validation outcome](#country-rules-and-validation).Unix timestamp (seconds).Unix timestamp (seconds).The identifier in full. Present only on [list tax registrations](#list-tax-registrations) for a key with `banking:read`; `null` everywhere else.
### List tax registrations
`GET /v1/vendors/{vendor_id}/tax_registrations`
Returns the vendor's tax registrations as a plain array, ordered by country and then by type. The list is not paginated.
**Auth:** any `ak_` key. With `banking:read`, each registration also carries `value`.
#### Path parameters
The vendor ID (`cbvndr_...`).
#### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/tax_registrations" \
-H "Authorization: Bearer ak_live_xxx"
```
#### Example response
`200 OK`, for a key without `banking:read`:
```json theme={null}
[
{
"id": "cbtaxreg_46718f0c9e091bd5e227e13030bfa2b2",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"country_code": "US",
"tax_id_type": "ein",
"value_masked": "****6789",
"validation_tier_reached": "format",
"format_status": "passed",
"registry_status": "pending",
"registry_provider": null,
"registry_checked_at": null,
"site_id": null,
"is_exempt": false,
"exemption_reason": null,
"evidence_document_id": null,
"validation_results": { "status": "passed", "results": [], "config_version": "2026.09.1" },
"created_at": 1790467305,
"updated_at": 1790467305,
"value": null
}
]
```
### Add or update a tax registration
`POST /v1/vendors/{vendor_id}/tax_registrations`
Saves a registration and returns `201 Created` with the [tax registration object](#the-tax-registration-object), whether it created a registration or updated one. A vendor holds one registration per country and type, and separately one per site, country and type: posting the same `country_code` and `tax_id_type` again (with the same `site_id`, or none) updates that registration. A new number restarts the register check. The `SupplierTaxRegistration.Updated` webhook fires in both cases.
**Auth:** any `ak_` key.
#### Path parameters
The vendor ID (`cbvndr_...`).
#### Request body
Two-letter country code of the registration.
The [tax ID type key](#tax-id-types) for that country, such as `ein`, `vat` or `tax_id`. Keys are case-sensitive. A key the country does not define is stored without any format or checksum check, so check the spelling.
The identifier, 1 to 64 characters. Required unless `is_exempt` is `true`, and refused when it is.
One of this vendor's active sites (`cbsite_...`), for a registration held at that address. Omit it for the supplier's own registration.
`true` records that the supplier is exempt from this registration instead of giving a number.
Why the supplier is exempt, up to 500 characters. Required when `is_exempt` is `true`.
A document already uploaded for this vendor with the [Documents API](/api-reference/documents) (`cbvdoc_...`), such as the registration certificate. A document of another vendor is refused with `422` and the code `invalid_document`. Omitting it on an update keeps the one already attached. In Argentina, Brazil, Chile, Colombia, Costa Rica, the Dominican Republic, Ecuador, Guatemala, Mexico, Panama, Paraguay, Peru and Uruguay, a registration without a certificate saves with a `tax_certificate.expected` warning.
#### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/tax_registrations" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"country_code": "US",
"tax_id_type": "ein",
"value": "12-3456789"
}'
```
The response is the saved registration, as in the [list example](#list-tax-registrations). The EIN is stored normalized, as `123456789`.
#### Error responses
| Status | Body | When |
| - | - | - |
| 422 | `{"detail": {"code": "invalid_site", "message": "site_id must be one of this supplier's sites."}}` | `site_id` is not an active site of this vendor. |
| 422 | `{"detail": {"code": "invalid_document", ...}}` | `evidence_document_id` is not a document of this vendor. |
| 422 | `{"detail": {"error": "validation_failed", ...}}` | An error-level country rule failed, such as a required identifier in the wrong format. |
| 422 | Standard validation error | `value` missing without an exemption, `value` sent with one, or `is_exempt` without an `exemption_reason`. |
## Diversity records
A diversity record is the supplier's declaration for one inclusion category, optionally backed by a certificate. Suppliers submit them through a questionnaire or the portal, and your staff can enter them on the **Know-Your-Vendor** tab. The API reads them but does not write them.
### List diversity records
`GET /v1/vendors/{vendor_id}/diversity_records`
Returns the vendor's diversity records as a plain array, ordered by category. The list is not paginated.
**Auth:** any `ak_` key.
#### Path parameters
The vendor ID (`cbvndr_...`).
#### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/diversity_records" \
-H "Authorization: Bearer ak_live_xxx"
```
#### Example response
`200 OK`:
```json theme={null}
[
{
"id": "cbdiv_a74e6a5bbc1ec1e2674eb5293c06e349",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"category": "women_owned",
"declared": true,
"jurisdiction": "US",
"business_size": "small",
"certification_type": "WBENC",
"certification_level": null,
"certificate_document_id": "cbvdoc_a490bd7dc71569f295096963d6e8f1d6",
"valid_from": 1767225600,
"valid_until": 1798761600,
"created_at": 1790467305,
"updated_at": 1790467305
}
]
```
#### Diversity record object
Diversity record ID (`cbdiv_...`).The vendor the record belongs to.`minority_owned`, `women_owned`, `veteran_owned`, `service_disabled_veteran_owned`, `disability_owned`, `lgbtq_owned`, `small_business`, `small_disadvantaged_business`, `hubzone`, `historically_black_college`, `indigenous_owned`, `aboriginal_owned`, `other`, or `none_declared`. `none_declared` is the supplier stating it holds none of the others, which is a different answer from never having been asked.Whether the supplier claims the category.Two-letter country code the certification applies in.`large`, `medium` or `small`, as certified. It is not worked out from headcount.The certifying body or program.The level of certification, where the program has levels.The certificate, as a vendor document (`cbvdoc_...`).Unix timestamp (seconds) the certificate is valid from.Unix timestamp (seconds) the certificate expires.Unix timestamp (seconds).Unix timestamp (seconds).
## Legal entities and assignments
Your **legal entities** are your own contracting entities, maintained under **Configuration → Legal entities**. An **assignment** says a supplier trades with one of them. The entity's `entity_code` is what your finance system matches on, and its country decides whether a payment to a supplier's bank account is `domestic` or `wire`.
### List your legal entities
`GET /v1/legal_entities`
Returns your organization's active legal entities as a plain array, ordered by name. Deactivated entities are left out. The list is not paginated.
**Auth:** any `ak_` key.
#### Query parameters
Case-insensitive substring match on the entity's name or entity code.
#### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/legal_entities?search=US01" \
-H "Authorization: Bearer ak_live_xxx"
```
#### Example response
`200 OK`:
```json theme={null}
[
{
"id": "cble_868dadcadf7b5162e3b103ac479e2d76",
"name": "Example Holdings US Inc.",
"entity_code": "US01",
"country_code": "US",
"description": null,
"active": true,
"created_at": 1788912000,
"updated_at": 1788912000
}
]
```
Legal entity ID (`cble_...`).The entity's name.The code your finance system knows the entity by.The country the entity pays from.A free-text description.Always `true` here.Unix timestamp (seconds).Unix timestamp (seconds).
### List a vendor's legal entity assignments
`GET /v1/vendors/{vendor_id}/legal_entity_assignments`
Returns every assignment for the vendor, newest first, including requested and rejected ones. The list is not paginated.
**Auth:** any `ak_` key.
#### Path parameters
The vendor ID (`cbvndr_...`).
#### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/legal_entity_assignments" \
-H "Authorization: Bearer ak_live_xxx"
```
#### Example response
`200 OK`:
```json theme={null}
[
{
"id": "cblea_bef2b5d73bc7e1bf253213acd076badb",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"legal_entity_id": "cble_868dadcadf7b5162e3b103ac479e2d76",
"legal_entity_name": "Example Holdings US Inc.",
"entity_code": "US01",
"site_id": "cbsite_f4f317ab5908a1a38899c0559f3ef3c1",
"status": "active",
"requested_by_id": "cbuser_c7a4e1e7349b2c82f050e4e948a1ed56",
"decided_at": 1790467305,
"rejection_reason": null,
"created_at": 1790467305
}
]
```
#### Legal entity assignment object
Assignment ID (`cblea_...`).The vendor.The legal entity (`cble_...`).The entity's name.The entity's code.The supplier site the assignment is for, if one was given.`requested` (waiting for approval), `active` or `rejected`.The user who requested it (`cbuser_...`). For an assignment made through the API, this is your organization's API service account.Unix timestamp (seconds) of the decision. Set at creation when no approval is needed.The reviewer's reason, for a rejected assignment.Unix timestamp (seconds).
### Assign legal entities
`POST /v1/vendors/{vendor_id}/legal_entity_assignments`
Assigns the vendor to one or more of your legal entities and returns `201 Created` with an array of the new [assignments](#legal-entity-assignment-object). The call is all or nothing: if any entity in the batch is already assigned, nothing is created.
Each assignment is `active` at once, and fires the `SupplierLegalEntityAssignment.Assigned` webhook with the entity code, unless **Legal entity assignments need approval** is on. Then it is `requested` until someone decides it in the dashboard. An active assignment's country feeds the payment method of bank accounts saved after it; an account already on file keeps its method until it is next saved.
**Auth:** any `ak_` key.
#### Path parameters
The vendor ID (`cbvndr_...`).
#### Request body
One to five legal entity IDs (`cble_...`) from [list your legal entities](#list-your-legal-entities). Each must be one of your active legal entities: an ID that is not, including a deactivated entity, fails the whole call and nothing is created.
One of this vendor's sites (`cbsite_...`) that the assignments are for.
The age in days, 0 to 3650, of the purchase requisition behind the request. Above 30 days, a `justification` is required. Omit it when no requisition is quoted.
Why a requisition older than 30 days should still be honored. Up to 500 characters.
#### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/legal_entity_assignments" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"legal_entity_ids": ["cble_868dadcadf7b5162e3b103ac479e2d76"],
"site_id": "cbsite_f4f317ab5908a1a38899c0559f3ef3c1",
"purchase_requisition_age_days": 12
}'
```
#### Error responses
| Status | Body | When |
| - | - | - |
| 400 | `{"detail": {"code": "invalid_site", "message": "site_id must be one of this supplier's sites."}}` | `site_id` is not one of this vendor's sites. |
| 409 | `{"detail": {"code": "duplicate_assignment", "message": "This supplier is already assigned to that legal entity.", "legal_entity_id": "cble_..."}}` | The vendor already has a requested or active assignment to that entity. A rejected one does not count. |
| 422 | `{"detail": {"code": "too_many_legal_entities", "message": "Select at most 5 legal entities at a time; 6 were sent.", "limit": 5}}` | More than five entities in one call. |
| 422 | `{"detail": {"code": "justification_required", "message": "...", "limit_days": 30}}` | `purchase_requisition_age_days` is over 30 and `justification` is empty. |
| 422 | `{"detail": {"code": "invalid_legal_entity", "message": "legal_entity_ids must name your organization's active legal entities.", "legal_entity_id": "cble_..."}}` | An ID in `legal_entity_ids` is not one of your organization's active legal entities. |
| 422 | Standard validation error | `legal_entity_ids` is empty or the body is malformed. |
## Update requests
An update request asks a supplier to review and update named sections of their profile. Coverbase sends the supplier no email: the request opens those sections on the **Profile** page of the [centralized supplier portal](/user-guides/centralized-supplier-portal#saying-which-part-needs-updating), where each is marked as one you asked about. It therefore reaches only a supplier who has a portal, in an organization that has turned the **Profile** section on. The sections stay open until the request expires, alongside any sections your organization leaves open all the time.
While a request is open, Coverbase reminds the vendor's relationship owners (or, if it has none, its risk analysts) 3 and 7 days after it was sent. When its expiry date passes, the request becomes `expired`.
### The update request object
Update request ID (`cbupdreq_...`).The vendor.The sections the request covers. See [send an update request](#send-an-update-request) for the values.The message stored with the request.The contact email you gave.The contact name you gave.`sent` while open, `draft` if created with `send: false`, and `expired` once past `expires_at`. The schema also lists `in_progress`, `submitted`, `reviewed` and `closed`; no current workflow moves a request into those.Unix timestamp (seconds) the request was sent.Unix timestamp (seconds) the supplier submitted.Unix timestamp (seconds) the request expires.The reminders already sent, by day: `3`, `7`.`null` for a request sent through the API.Unix timestamp (seconds).Unix timestamp (seconds).
### List update requests
`GET /v1/vendors/{vendor_id}/update_requests`
Returns the vendor's update requests as a plain array, newest first. The list is not paginated.
**Auth:** any `ak_` key.
#### Path parameters
The vendor ID (`cbvndr_...`).
#### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/update_requests" \
-H "Authorization: Bearer ak_live_xxx"
```
### Send an update request
`POST /v1/vendors/{vendor_id}/update_requests`
Creates a request and, unless `send` is `false`, sends it. Returns `201 Created` with the [update request object](#the-update-request-object). The dashboard has no button for this; the API is the only way to send one.
**Auth:** any `ak_` key.
#### Path parameters
The vendor ID (`cbvndr_...`).
#### Request body
The sections to open, from the values in the table below. Omit it or send `[]` to use **Sections to request by default** from **Know Your Vendor Settings**, which is `po_email`, `addresses` and `bank_accounts` unless your organization changed it.
| `field_scope` value | Section it opens |
| - | - |
| `po_email` | Where purchase orders and remittance advice are emailed |
| `addresses` | Sites |
| `bank_accounts` | Bank accounts. Changes still wait for review. |
| `tax_registrations` | Tax registrations and exemptions |
| `diversity` | Diversity records |
| `contacts` | Contact details. Only a request can open this section. |
| `legal_entities` | The supplier's legal entities. Only a request can open this section. |
A message stored with the request, up to 2000 characters.
The supplier contact the request is for. Stored and returned as `recipient_email`; Coverbase does not email it.
The contact's name, returned as `recipient_name`.
`false` saves the request as a `draft`, which opens nothing. No endpoint sends a draft later.
The request expires after **Request expires after (days)** in **Know Your Vendor Settings**, 30 days by default.
#### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/update_requests" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"field_scope": ["bank_accounts", "po_email"],
"message": "Please confirm your remittance details before the Q4 payment run.",
"contact_email": "ap@supplier1.example.com",
"contact_name": "Jordan Lee"
}'
```
## The change feed
Changes to your vendors' supplier profiles are appended to one org-wide history of **change events** (`cbpce_...`), and nothing edits or deletes an event once written. The feed returns that history oldest first. Use it to reconcile after missed webhooks, or poll it instead of receiving webhooks at all.
### The change event object
Change event ID (`cbpce_...`). Webhooks for the same change carry it as `change_event_id`, so use it to deduplicate across the two.The vendor the change belongs to.What changed: `bank_account`, `site`, `tax_registration`, `diversity_record` or `legal_entity_assignment`.The ID of the record that changed. For a queued or rejected bank change, it is the review ID (`cbbarev_...`).`created`, `updated`, `deleted`, `retired`, `submitted`, `approved`, `rejected` or `revealed`. See [what the feed records](#what-the-feed-records).`supplier_portal`, `internal_user`, `api` or `system`.Who made the change, for display: `API`, `Supplier portal` (a questionnaire answer), a portal user's email address, a staff member's name, or `null`.`sensitive` for every bank account event, `normal` otherwise.The fields that changed, each as `{ "old_value", "new_value" }`. Account and tax numbers appear only as their last four characters.The record as saved after the change, masked the same way. A legal entity assignment's snapshot includes the entity's `entity_code` and the site.Unix timestamp (seconds).
### What the feed records
The feed is the audit trail, so it holds more than the webhooks send. Filter on `action` before you apply anything to your finance system.
| What happened | Feed event (`entity_type`, `action`) | Webhook |
| - | - | - |
| A bank change is queued for review | `bank_account`, `submitted`; `entity_id` is the review | None |
| A reviewer approves it | `bank_account`, `approved`; `entity_id` is the account | `VendorBankAccount.Updated`, also for a new account |
| A reviewer rejects it | `bank_account`, `rejected`; `entity_id` is the review | None |
| A bank account is saved without review | `bank_account`, `created` or `updated` | `VendorBankAccount.Created` or `.Updated` |
| A bank account is retired | `bank_account`, `retired` | `VendorBankAccount.Retired` |
| Someone reveals a full account number in the dashboard | `bank_account`, `revealed` | None |
| A site is added, changed or deleted | `site`, `created`, `updated` or `deleted` | `SupplierSite.Created`, `.Updated` or `.Deleted` |
| A tax registration is saved | `tax_registration`, `updated` | `SupplierTaxRegistration.Updated` |
| A diversity record is saved | `diversity_record`, `updated` | `SupplierDiversityRecord.Updated` |
| An assignment is requested and needs approval | `legal_entity_assignment`, `created`; snapshot `status` is `requested` | None |
| An assignment takes effect on request | `legal_entity_assignment`, `created` | `SupplierLegalEntityAssignment.Assigned` |
| An assignment is approved or rejected | `legal_entity_assignment`, `approved` or `rejected` | `SupplierLegalEntityAssignment.Assigned` or `.Rejected` |
### List changes
`GET /v1/vendors/changes`
Returns one page of change events across all vendors, oldest first.
**Auth:** any `ak_` key.
#### Query parameters
Unix timestamp (seconds). Returns events at or after this time. Omit it to start from the first event.
Only these `entity_type` values, from the five above. Repeat the parameter for more than one: `types=bank_account&types=site`. Any other value is rejected with `422`.
The `next_cursor` from the previous page. Treat it as opaque. A cursor Coverbase cannot read is ignored, and the feed starts again from `since`, or from the first event without one.
Page size, 1 to 500.
#### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/vendors/changes?since=1790467200&types=bank_account&types=site&limit=100" \
-H "Authorization: Bearer ak_live_xxx"
```
#### Example response
`200 OK`:
```json theme={null}
{
"data": [
{
"id": "cbpce_db06d169f2a31db2c958c00245da9791",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"entity_type": "bank_account",
"entity_id": "cbbarev_6f1085b71efca801572074863961a938",
"action": "submitted",
"actor_type": "api",
"actor_label": "API",
"sensitivity": "sensitive",
"diff": {
"account_number": { "old_value": null, "new_value": "****6789" },
"account_type": { "old_value": null, "new_value": "checking" },
"bank_code": { "old_value": null, "new_value": "" },
"bank_name": { "old_value": null, "new_value": "First Example Bank" },
"branch_code": { "old_value": null, "new_value": "076401251" },
"swift_bic": { "old_value": null, "new_value": "" }
},
"snapshot": {
"id": "cbbarev_6f1085b71efca801572074863961a938",
"bank_account_id": null,
"bank_country": "US",
"currency": "USD",
"account_number_masked": "****6789",
"iban_masked": null,
"is_primary": true,
"status": "pending_review",
"validation_status": "passed"
},
"created_at": 1790467305
},
{
"id": "cbpce_4bba10d3fe8712d8b69fbb6074fd2456",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"entity_type": "site",
"entity_id": "cbsite_f4f317ab5908a1a38899c0559f3ef3c1",
"action": "updated",
"actor_type": "api",
"actor_label": "API",
"sensitivity": "normal",
"diff": {
"address_line1": { "old_value": "45 Harbour Road", "new_value": "200 Park Avenue" },
"address_line2": { "old_value": null, "new_value": "Floor 12" },
"postal_code": { "old_value": "10001", "new_value": "10166" }
},
"snapshot": {
"id": "cbsite_f4f317ab5908a1a38899c0559f3ef3c1",
"address_line1": "200 Park Avenue",
"address_line2": "Floor 12",
"address_line3": null,
"address_line4": null,
"city": "New York",
"state_province": "NY",
"county": null,
"postal_code": "10166",
"country_code": "US",
"site_name": "Global HQ",
"description": "",
"address_purpose": "primary",
"location_code": "NY-HQ-01",
"csp_remit_to_id": null,
"tax_region": "US-NY",
"po_emails": [],
"remittance_emails": [],
"is_primary": true,
"status": "active"
},
"created_at": 1790467305
}
],
"next_cursor": "eyJ0IjogMTc5MDQ2NzMwNSwgImkiOiAiY2JwY2VfNGJiYTEwZDNmZTg3MTJkOGI2OWZiYjYwNzRmZDI0NTYifQ==",
"has_more": true
}
```
The page of [change events](#the-change-event-object), oldest first.Pass it as `cursor` to get the next page. `null` on the last page.Whether another page follows.
#### Keeping up with the feed
Page with `cursor` until `has_more` is `false`. The last page carries no cursor, so remember the `created_at` of the last event you applied and pass it as `since` on your next poll. Events from that same second come back again, so skip any `id` you have already applied.
## Field keys
The API names each field by a key, while the dashboard and the supplier's form show a label that differs by country. These keys come from the rules Coverbase ships for each country. If Coverbase has overridden a country's rules for your organization, ask your account team which keys changed.
### Bank account values
Every country uses the same keys for the common fields, whatever the form calls them:
| Key | Holds | Labels it appears under |
| - | - | - |
| `account_number` | The account number | Account number |
| `branch_code` | The branch or routing code | Sort Code (United Kingdom), Routing Transit Number (United States), BSB (Australia), Transit number (Canada), IFSC Code (India), Agência (Brazil) |
| `bank_code` | The bank's own code | Bank code, Institution number (Canada), Bankleitzahl (Germany), CNAPS code (China) |
| `bank_name` | The bank's name | Bank name |
| `iban` | The IBAN | IBAN |
| `swift_bic` | The SWIFT/BIC | SWIFT/BIC |
| `check_digit` | Check digits, where the country uses them | Check digit |
| `account_type` | `checking` or `savings`. Required in Brazil, China, Hong Kong and the United States; not used in Japan. | Account type |
Nine countries add their own:
| Country | Extra keys |
| - | - |
| Australia, China | `intermediary_bank_name`, `intermediary_swift_bic`, `intermediary_account_number` |
| Brazil | `company_code` |
| Colombia | `branch_name`, `tax_payer_id` (the bank's taxpayer ID) |
| Japan | `beneficiary_name` (account holder, in half-width katakana), `bank_name_local`, `branch_name_local`, and `deposit_type` (`futsu`, `toza` or `chochiku`) in place of `account_type` |
| Mexico | `clabe` |
| Peru | `cci` |
| Sweden | `bankgiro` |
| United Kingdom | `building_society_roll_number` |
Which keys a country requires is on its page under [Supplier countries](/user-guides/supplier-countries/overview).
### Tax ID types
Sixty-nine countries use a single key, `tax_id`, for their tax or VAT number. The other forty use the keys below.
| Country | `tax_id_type` keys |
| - | - |
| Australia | `abn` |
| Brazil | `cnpj` |
| Bulgaria | `uic`, `vat` |
| Canada | `business_number` |
| Chile | `rut` |
| China | `uscc` |
| Colombia | `nit` |
| Côte d'Ivoire | `compte_contribuable` |
| Finland | `y_tunnus` |
| France | `siren`, `siret`, `vat` |
| Germany | `vat` |
| Ghana | `tin` |
| Hong Kong SAR | `brn` |
| India | `pan`, `gstin` |
| Indonesia | `npwp` |
| Ireland | `vat` |
| Italy | `partita_iva` |
| Japan | `corporate_number` |
| Malaysia | `tin` |
| Mauritius | `tan` |
| Mexico | `rfc` |
| Netherlands | `kvk`, `btw` |
| Nigeria | `tin` |
| Oman | `vatin` |
| Peru | `ruc` |
| Philippines | `tin` |
| Poland | `nip` |
| Portugal | `nif` |
| Saudi Arabia | `vat_tin` |
| Singapore | `uen` |
| South Africa | `tax_ref`, `cipc_reg` |
| South Korea | `brn` |
| Spain | `nif_cif` |
| Sweden | `orgnr` |
| Switzerland | `uid` |
| Thailand | `tin` |
| Türkiye | `vkn` |
| United Arab Emirates | `trn` |
| United Kingdom | `company_number`, `vat` |
| United States | `ein` |
# Users API
Source: https://docs.coverbase.com/api-reference/users
Provision users, change org roles, and deprovision, for SailPoint / IGA-driven lifecycle.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Users API provisions Coverbase accounts and manages their organization role and lifecycle. It is designed for identity-governance (SailPoint / IGA) integrations: the upstream system owns approval, this API creates the account + org membership so SSO can authenticate the user on first login.
Provisioning creates the Coverbase account and an org membership in **`invited`** status. It does **not** create a login session. The user is linked to your IdP by email on first SSO. SailPoint owns the upstream approval; this API only reflects role/lifecycle into Coverbase.
All endpoints are org-scoped to the API key. See [API conventions](/conventions) for shared behavior.
| Method | Path | Idempotent |
| - | - | - |
| `POST` | `/v1/users` | Yes (`Idempotency-Key`) |
| `GET` | `/v1/users` | - |
| `GET` | `/v1/users/{user_id}` | - |
| `PATCH` | `/v1/users/{user_id}` | No |
Syncing relationship owners, watchers, or risk analysts from an external system (for example, ServiceNow)? Those [vendor/service fields](/api-reference/vendors#assigning-people-analysts-owners-watchers) take Coverbase user IDs, not emails. Use [`GET /v1/users?email=`](#list-users-and-look-up-by-email) to resolve an email to its `cbuser_...` ID, and `POST /v1/users` to create the user if they don't exist yet; it returns the existing user if they do.
## Org roles
The `role` field uses these values:
| Value | Role |
| - | - |
| `org:admin` | Admin |
| `org:member` | Member |
| `org:siloed_member` | Siloed member |
| `org:guest` | Guest |
| `org:auxiliary_member` | Auxiliary member |
| `org:service_account` | Service account |
Only these exact values are accepted; anything else, including shorthand such as `member` or `admin`, is rejected with `422`. On read, `role` can also be `org:custom` for a member who holds a custom role defined in your organization. That value cannot be assigned through this API.
If your organization uses custom roles and permissions, a caller can only assign a role whose permissions it holds itself. Assigning a role above the caller's own permissions returns `403 role_escalation`.
## Provision a user (create-or-get)
`POST /v1/users`
Creates the account + org membership (`invited`), or returns the existing user. Returns `201 Created` on create, or **`200 OK`** if a user with that email already exists in the org. This call is safe to use as create-if-missing and always yields the user's `cbuser_...` ID.
Idempotent create-or-get: a same-org email match returns `200` with the existing user (not `409`). A `409 user_exists` is only returned when the email belongs to a user in a **different** org (emails are globally unique). The email match is case-insensitive.
### Request body
The user's email, validated as a proper email address. Used to link the account to your IdP on first SSO.
Given name.
Family name.
One of the [org role values](#org-roles). Defaults to `org:member`.
### Headers
`Bearer ak_...`
Optional. Replaying the same key within 24 hours returns the original `201` body. See [Idempotency](/conventions#idempotency).
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/users" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Idempotency-Key: acme-user-jordanlee" \
-H "Content-Type: application/json" \
-d '{
"email": "jordan.lee@example.com",
"first_name": "Jordan",
"last_name": "Lee",
"role": "org:admin"
}'
```
```python Python theme={null}
import os
import requests
API_KEY = os.environ["COVERBASE_API_KEY"]
BASE_URL = "https://api.coverbase.app"
resp = requests.post(
f"{BASE_URL}/v1/users",
headers={
"Authorization": f"Bearer {API_KEY}",
"Idempotency-Key": "acme-user-jordanlee",
"Content-Type": "application/json",
},
json={
"email": "jordan.lee@example.com",
"first_name": "Jordan",
"last_name": "Lee",
"role": "org:admin",
},
timeout=30,
)
# 201 on create; 200 if the email already exists in this org
print(resp.status_code, resp.json())
```
### Example response
`201 Created` (new user), or `200 OK` (existing user; the stored object, whose `status` is its current membership state such as `active`):
```json theme={null}
{
"id": "cbuser_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"email": "jordan.lee@example.com",
"first_name": "Jordan",
"last_name": "Lee",
"role": "org:admin",
"status": "invited",
"is_archived": false,
"created_at": 1746576000,
"updated_at": 1746576000
}
```
### User object
User ID (`cbuser_...`).User email.Given name.Family name.Org role value for this org (for example, `org:admin`).Org membership status: `invited`, `active`, or `inactive`.`true` once the user is deprovisioned.Unix timestamp (seconds).Unix timestamp (seconds).
### Error responses
| Status | Body | When |
| - | - | - |
| 403 | `{"detail": {"code": "role_escalation", "message": "...", "offending": [...]}}` | `role` grants permissions the caller does not hold. |
| 409 | `{"detail": {"code": "user_exists", "message": "A user with email ... already exists."}}` | The email belongs to a user in a **different** org (emails are globally unique). A same-org match now returns `200` with the existing user, not `409`. |
| 422 | Standard validation error | `email` missing or not a valid email address, or `role` not a recognized value. |
## List users and look up by email
`GET /v1/users`
Lists the org's users, newest first, or resolves a single user by email. By default the list holds invited and active members, the people the dashboard shows. This is the supported way to build an **email → user ID** mapping when syncing assignments (relationship owners, watchers, risk analysts) from an external system such as ServiceNow; those fields take Coverbase user IDs, so resolve the email here first.
### Query parameters
Case-insensitive exact-match lookup. Returns the matching user (even if archived, so it can be reactivated) or an empty list. Uses the same matching as the `POST /v1/users` duplicate check, so any email that exists is resolvable to its user ID. When supplied, `include_archived`/`limit`/`offset` are ignored.
Also include archived users and deprovisioned (`inactive`) memberships. Defaults to `false`.
Page size, `1`-`200`. Defaults to `50`.
Number of users to skip, for paging. Defaults to `0`.
### Headers
`Bearer ak_...`
### Example: resolve a user by email
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/users?email=jordan.lee@example.com" \
-H "Authorization: Bearer ak_live_xxx"
```
```python Python theme={null}
import os
import requests
API_KEY = os.environ["COVERBASE_API_KEY"]
BASE_URL = "https://api.coverbase.app"
resp = requests.get(
f"{BASE_URL}/v1/users",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"email": "jordan.lee@example.com"},
timeout=30,
)
resp.raise_for_status()
items = resp.json()["items"]
user_id = items[0]["id"] if items else None # resolve email -> cbuser_ id
```
### Example response
`200 OK`:
```json theme={null}
{
"items": [
{
"id": "cbuser_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"email": "jordan.lee@example.com",
"first_name": "Jordan",
"last_name": "Lee",
"role": "org:admin",
"status": "active",
"is_archived": false,
"created_at": 1746576000,
"updated_at": 1746576000
}
],
"total": 1,
"limit": 50,
"offset": 0
}
```
### Response fields
Page of [user objects](#user-object). `role` and `status` reflect each user's membership in the API key's org.Total matching users in the org (for an `email` lookup this is `0` or `1`).Echo of the requested page size.Echo of the requested offset.
To create-if-missing and always end up with the user's ID: look up the email here, and if `items` is empty call `POST /v1/users` to provision them; or call `POST /v1/users` directly, which returns the existing user (`200`) when the email is already present.
## Retrieve a user
`GET /v1/users/{user_id}`
Returns the user. The user must have a membership in the API key's org.
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/users/cbuser_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6" \
-H "Authorization: Bearer ak_live_xxx"
```
Returns the [user object](#user-object). `role` and `status` reflect the current org membership.
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "user_not_found", "message": "User not found."}}` | No such user, or the user has no membership in the API key's org. |
## Update role / deprovision
`PATCH /v1/users/{user_id}`
Changes a user's org role and/or (de)provisions them. Returns the refreshed [user object](#user-object).
### Request body
New org role (one of the [role values](#org-roles)). Omit to leave unchanged.
`true` deprovisions: archives the user and sets org membership to `inactive`. `false` reactivates: membership back to `active`. Omit to leave unchanged.
### Examples
```bash Change role theme={null}
curl -X PATCH "https://api.coverbase.app/v1/users/cbuser_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "role": "org:member" }'
```
```bash Deprovision theme={null}
curl -X PATCH "https://api.coverbase.app/v1/users/cbuser_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "is_archived": true }'
```
### Behavior
* `is_archived: true` → user archived, membership `inactive`.
* `is_archived: false` → membership `active` (reactivation).
* `role` set → membership role updated.
* Combined (`role` + `is_archived`) is applied together.
### Error responses
| Status | Body | When |
| - | - | - |
| 403 | `{"detail": {"code": "role_escalation", "message": "...", "offending": [...]}}` | `role` grants permissions the caller does not hold. |
| 404 | `{"detail": {"code": "user_not_found", "message": "User not found."}}` | No membership for this user in the API key's org. |
| 409 | `{"detail": {"code": "role_requires_invitation", "message": "Invite this person to the organization to give them a role."}}` | The person has a Coverbase account owned by another organization and is only named on your records. Invite them from the dashboard to give them a role. |
| 422 | Standard validation error | `role` not a recognized value. |
# Vendors & Services API
Source: https://docs.coverbase.com/api-reference/vendors
Create, retrieve, and update vendors, and create child services.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A **vendor** (`cbvndr_...`) is a parent supplier entity. A **service** (`cbsvc_...`) is a child entity under a vendor. This API creates and reads both.
All endpoints are org-scoped to the API key. See [API conventions](/conventions) for authentication, IDs, timestamps, idempotency, and the error envelope.
To upload, version, and search bills of materials (SBOM, AIBOM, HBOM, SaaSBOM) for a vendor or service, see the [Bill of Materials API](/api-reference/bill-of-materials).
To upload evidence documents (SOC 2 reports, policies, contracts, questionnaires) for a vendor and link them to its services and assessments, see the [Documents API](/api-reference/documents).
To read and write a vendor's bank accounts, sites, tax registrations and legal entity assignments, see the [Supplier Profile API](/api-reference/supplier-profile).
| Method | Path | Idempotent |
| - | - | - |
| `POST` | `/v1/vendors` | Yes (`Idempotency-Key`) |
| `GET` | `/v1/vendors` | - |
| `GET` | `/v1/vendors/{vendor_id}` | - |
| `PATCH` | `/v1/vendors/{vendor_id}` | No |
| `POST` | `/v1/vendors/{vendor_id}/services` | No |
| `PATCH` | `/v1/vendors/{vendor_id}/services/{service_id}` | No |
| `GET` | `/v1/vendors/{vendor_id}/fact-sheet` | - |
| `POST` | `/v1/vendors/{vendor_id}/fact-sheet/refresh` | No |
## The primary contact object
Both vendor and service endpoints accept/return a `primary_contact`. On a vendor it is the address the inherent-risk-questionnaire portal invite (and other vendor emails) are sent to; on a service it is the service-level point-of-contact.
| Field | Type | Notes |
| - | - | - |
| `email` | string | **Required**, validated as an email address. |
| `name` | string \| null | Contact name. |
| `title` | string \| null | Contact title. |
| `phone_number` | string \| null | Contact phone. |
On read, `primary_contact` is derived from the stored contact personnel (first entry with an email); for vendors it falls back to the vendor's security contact email. It is `null` if no contact is set.
## Assigning people (analysts, owners, watchers)
Vendors and services accept optional personnel assignments as arrays of user IDs (`cbuser_...`). All are **optional**; on create, omit them to assign no one. On update (`PATCH`), supplying an array **replaces** the existing set; pass `[]` to clear it, or omit the field to leave it unchanged.
| Field | Vendor | Service | Meaning |
| - | - | - | - |
| `risk_analyst_ids` | ✓ | - | Risk analysts. **Vendor-only**: services do not have risk analysts. |
| `relationship_owner_ids` | ✓ | ✓ | Relationship owners. |
| `watcher_ids` | ✓ | ✓ | Watchers (users who follow the vendor/service for notifications). |
These fields take Coverbase user IDs, not emails. Syncing from an external system (for example, ServiceNow) that keys on email? Use the [Users API](/api-reference/users#list-users-and-look-up-by-email) to resolve an email to its `cbuser_...` ID; `GET /v1/users?email=` looks one up, and `POST /v1/users` provisions the user if they don't exist yet (returning the existing user if they do).
## Create a vendor
`POST /v1/vendors`
Creates a parent vendor. Returns `201 Created` with the full vendor object.
### Request body
Vendor name.
Vendor website URL.
Vendor description.
Headquarters location.
How the vendor is used within the organization.
Your system's identifier for this vendor (for example, an Ariba request ID). Stored and echoed back; useful for correlation.
Risk analyst user IDs (`cbuser_...`) to assign. See [assigning people](#assigning-people-analysts-owners-watchers).
Relationship owner user IDs (`cbuser_...`) to assign.
Watcher user IDs (`cbuser_...`) to assign.
The vendor point-of-contact (see [the primary contact object](#the-primary-contact-object)). If supplied, `email` is required and validated.
### Headers
`Bearer ak_...`
Optional. Replaying the same key within 24 hours returns the original `201` body. See [Idempotency](/conventions#idempotency).
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/vendors" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Idempotency-Key: acme-vendor-test1" \
-H "Content-Type: application/json" \
-d '{
"name": "ACME_Sup_Test1",
"website": "https://supplier1.example.com",
"use_case": "Demo supplier for Acme Inc",
"external_id": "ariba-req-7821"
}'
```
```python Python theme={null}
import os
import requests
API_KEY = os.environ["COVERBASE_API_KEY"]
BASE_URL = "https://api.coverbase.app"
resp = requests.post(
f"{BASE_URL}/v1/vendors",
headers={
"Authorization": f"Bearer {API_KEY}",
"Idempotency-Key": "acme-vendor-test1",
"Content-Type": "application/json",
},
json={
"name": "ACME_Sup_Test1",
"website": "https://supplier1.example.com",
"use_case": "Demo supplier for Acme Inc",
"external_id": "ariba-req-7821",
},
timeout=30,
)
resp.raise_for_status()
print(resp.json())
```
### Example response
`201 Created`: the full vendor object (see [response fields](#vendor-object) below):
```json theme={null}
{
"id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"external_id": "ariba-req-7821",
"name": "ACME_Sup_Test1",
"website": "https://supplier1.example.com",
"description": null,
"hq_location": null,
"status": null,
"status_id": null,
"tags": [],
"risk_analyst_ids": [],
"relationship_owner_ids": [],
"watcher_ids": [],
"inherent_risk_level_id": null,
"residual_risk_level_id": null,
"engagement_type": "vendor",
"use_case": "Demo supplier for Acme Inc",
"tier": null,
"primary_contact": null,
"services": [],
"custom_fields": [],
"created_at": 1746576000,
"updated_at": 1746576000
}
```
### Error responses
| Status | Body | When |
| - | - | - |
| 400 | `{"detail": {"code": "invalid_vendor", "message": "..."}}` | Creation rejected by a business rule. |
| 422 | Standard validation error | `name` missing, body malformed, or `primary_contact.email` not a valid email. |
## Create a child service
`POST /v1/vendors/{vendor_id}/services`
Creates a service under an existing vendor. Returns `201 Created`.
This endpoint does **not** honor `Idempotency-Key`; sending the header is harmless but has no effect. Retrying after a successful create makes a second service.
### Path parameters
The parent vendor ID (`cbvndr_...`).
### Request body
Service name.
Service description.
Your system's identifier for this service.
Tag IDs (`cbtag_...`) to attach to the service.
Relationship owner user IDs (`cbuser_...`) to assign. See [assigning people](#assigning-people-analysts-owners-watchers).
Watcher user IDs (`cbuser_...`) to assign.
The service point-of-contact (see [the primary contact object](#the-primary-contact-object)). If supplied, `email` is required and validated.
Services do **not** have risk analysts; risk analysts are assigned on the parent vendor. Sending `risk_analyst_ids` to a service endpoint has no effect.
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/services" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"name": "ACME_Sup_Test1 - Primary Service",
"relationship_owner_ids": ["cbuser_e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"],
"watcher_ids": ["cbuser_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"],
"primary_contact": { "email": "service-owner@supplier1.example.com" }
}'
```
### Example response
`201 Created` (see [the service object](#service-object)):
```json theme={null}
{
"id": "cbsvc_3c2b1a098f7e6d5c4b3a2918374655ab",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"name": "ACME_Sup_Test1 - Primary Service",
"description": null,
"external_id": null,
"tags": [],
"relationship_owner_ids": ["cbuser_e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"],
"watcher_ids": ["cbuser_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"],
"primary_contact": { "email": "service-owner@supplier1.example.com", "name": null, "title": null, "phone_number": null },
"created_at": 1746576000
}
```
### Service object
Service ID (`cbsvc_...`).The parent vendor ID.Service name.Service description.Your external identifier, if supplied.Tag value strings (empty array if none).Relationship owner user IDs (`cbuser_...`). Empty array if none.Watcher user IDs (`cbuser_...`). Empty array if none.The service point-of-contact (see [the primary contact object](#the-primary-contact-object)), or `null`.Values your organization has set on this service. Empty array if none are set, and always empty on a create response. See the [Custom Fields API](/api-reference/custom-fields).Unix timestamp (seconds).
### Error responses
| Status | Body | When |
| - | - | - |
| 400 | `{"detail": {"code": "invalid_service", "message": "..."}}` | Creation rejected by a business rule. |
| 404 | `{"detail": {"code": "vendor_not_found", "message": "Vendor not found."}}` | `vendor_id` does not exist or is not in the API key's org. |
| 422 | Standard validation error | `name` missing or body malformed. |
## Update a service
`PATCH /v1/vendors/{vendor_id}/services/{service_id}`
Updates a service. Only included fields change. Returns the updated [service object](#service-object).
### Path parameters
The parent vendor ID (`cbvndr_...`).
The service ID (`cbsvc_...`). Must belong to `vendor_id`.
### Request body
Service name.Service description.Replace the service's tag set (tag IDs `cbtag_...`).Replace the relationship owner set (user IDs `cbuser_...`). Pass `[]` to clear.Replace the watcher set (user IDs `cbuser_...`). Pass `[]` to clear.Replace the service point-of-contact (see [the primary contact object](#the-primary-contact-object)). When supplied, `email` is required and validated.
`external_id` is set only at creation and is not updatable here. Services do not have risk analysts.
### Example request
```bash cURL theme={null}
curl -X PATCH "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/services/cbsvc_3c2b1a098f7e6d5c4b3a2918374655ab" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "name": "ACME_Sup_Test1 - Renamed Service" }'
```
### Error responses
| Status | Body | When |
| - | - | - |
| 400 | `{"detail": {"code": "invalid_service", "message": "..."}}` | Update rejected by a business rule. |
| 404 | `{"detail": {"code": "service_not_found", "message": "Service not found."}}` | The service does not exist, or does not belong to `vendor_id`, or is not in the API key's org. |
| 422 | Standard validation error | Body failed schema validation. |
## List vendors
`GET /v1/vendors`
Lists vendors in the API key's org, newest first. Without filters it returns
every vendor, paginated. Use it to enumerate vendors, resolve a vendor by name,
or map your own identifier to a Coverbase vendor ID.
List rows are a **lightweight summary**; they omit the nested `services` and
the personnel-assignment arrays. Fetch [`GET /v1/vendors/{vendor_id}`](#retrieve-a-vendor)
for the full object.
### Query parameters
Case-insensitive substring match on the vendor (or service) name.
Exact match on the vendor's `external_id`; handy for mapping your system's
identifier back to a Coverbase vendor.
Page size, 1-200.
Number of rows to skip, for pagination.
Populate `custom_fields` on each row. Off by default so listing stays cheap;
single-vendor reads always include them. See the
[Custom Fields API](/api-reference/custom-fields).
### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/vendors?name=acme&limit=50" \
-H "Authorization: Bearer ak_live_xxx"
```
### Example response
`200 OK`:
```json theme={null}
{
"items": [
{
"id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"external_id": "ariba-req-7821",
"name": "ACME_Sup_Test1",
"website": "https://supplier1.example.com",
"description": null,
"hq_location": null,
"status": "Active",
"status_id": "cbst_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"tags": ["saas"],
"use_case": "Customer support ticketing",
"tier": "tier_2",
"primary_contact": null,
"created_at": 1732292930,
"updated_at": 1746575800
}
],
"total": 1,
"limit": 50,
"offset": 0
}
```
The page of vendor summaries. Each carries `id`, `external_id`, `name`,
`website`, `description`, `hq_location`, `status`, `status_id`, `tags`,
`use_case`, `tier`, `primary_contact`, `custom_fields`, `created_at`, and
`updated_at`. (No `services` or personnel arrays; see the note above.)
`custom_fields` is empty unless you pass `include_custom_fields=true`.
Total vendors matching the filters (across all pages).The page size used.The offset used.
## Retrieve a vendor
`GET /v1/vendors/{vendor_id}`
### Path parameters
The vendor ID (`cbvndr_...`).
### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162" \
-H "Authorization: Bearer ak_live_xxx"
```
### Example response
```json theme={null}
{
"id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"external_id": "ariba-req-7821",
"name": "ACME_Sup_Test1",
"website": "https://supplier1.example.com",
"description": "Enterprise customer support tooling provider",
"hq_location": "San Francisco, CA",
"status": "Active",
"status_id": "cbst_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"tags": ["processes_pii", "saas"],
"risk_analyst_ids": ["cbuser_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"],
"relationship_owner_ids": ["cbuser_e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"],
"watcher_ids": ["cbuser_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"],
"inherent_risk_level_id": "cbsclvl_7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d",
"residual_risk_level_id": "cbsclvl_3f4e5d6c7b8a9b0c1d2e3f4a5b6c7d8e",
"engagement_type": "vendor",
"use_case": "Customer support ticketing",
"tier": "tier_2",
"primary_contact": {
"email": "security@supplier1.example.com",
"name": "Jordan Lee",
"title": "CISO",
"phone_number": "+1-555-0100"
},
"services": [
{
"id": "cbsvc_3c2b1a098f7e6d5c4b3a2918374655ab",
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"name": "ACME_Sup_Test1 - Primary Service",
"description": null,
"external_id": null,
"tags": [],
"relationship_owner_ids": [],
"watcher_ids": [],
"primary_contact": null,
"custom_fields": [],
"created_at": 1746576000
}
],
"custom_fields": [
{
"config_id": "cbcfc_8b1e4a7d0c3f6a9b2e5d8c1f4a7b0e3d",
"field_name": "Exception Status",
"field_type": "select",
"value": "Open"
}
],
"created_at": 1732292930,
"updated_at": 1746575800
}
```
### Vendor object
Vendor ID (`cbvndr_...`).Your external identifier, if set.Vendor name.Vendor website URL.Vendor description.Headquarters location.Current status as a plain label string (for example, `"Active"`). Org-customizable. `null` if unset.ID (`cbst_...`) of the current status record.Tag value strings (empty array if none).Assigned risk analyst user IDs (`cbuser_...`).Relationship owner user IDs (`cbuser_...`).Watcher user IDs (`cbuser_...`).Scale level ID (`cbsclvl_...`) for inherent risk.Scale level ID (`cbsclvl_...`) for residual risk.How this vendor engages with your organization: `vendor` or `product`.How the vendor is used.Derived vendor tier (for example, `tier_1`, `tier_2`). Set by workflow tiering actions; `null` until derived.The vendor point-of-contact (see [the primary contact object](#the-primary-contact-object)), or `null`.The vendor's child services, each a [service object](#service-object). Empty array if none.Values your organization has set on this vendor. Empty array if none are set. See the [Custom Fields API](/api-reference/custom-fields) for the value shapes. Nested services carry their own `custom_fields`.Unix timestamp (seconds) of creation.Unix timestamp (seconds) of last update.
### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "vendor_not_found", "message": "Vendor not found."}}` | `vendor_id` does not exist or is not in the API key's org. |
## Update a vendor
`PATCH /v1/vendors/{vendor_id}`
Updates one or more fields. Only included fields change; omitted fields are untouched. The full, refreshed vendor object is returned.
Every body field is optional. Sending `null` for a field is treated the same as omitting it (no change); there is no clear-to-null behavior.
### Request body
Vendor name.Vendor website URL.Vendor description.Headquarters location.ID (`cbst_...`) of a status record to transition to.Replace the entire tag set, using tag IDs (`cbtag_...`).Replace the risk analyst set (user IDs `cbuser_...`). Pass `[]` to clear.Replace the relationship owner set (user IDs `cbuser_...`). Pass `[]` to clear.Replace the watcher set (user IDs `cbuser_...`). Pass `[]` to clear.Scale level ID (`cbsclvl_...`) for inherent risk.Scale level ID (`cbsclvl_...`) for residual risk.How the vendor is used.How this vendor engages with your organization: `vendor` or `product`. Any other value returns `422`.Replace the vendor point-of-contact (see [the primary contact object](#the-primary-contact-object)). When supplied, `email` is required and validated.
`external_id` and `tier` are **not** updatable through this endpoint (`external_id` is set only at creation; `tier` is derived by workflows).
### Example request
```bash cURL theme={null}
curl -X PATCH "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"status_id": "cbst_offboarding7f8e9d0c1b2a3f4e5d6c7b8a9f0e1d2c",
"use_case": "Legacy system, winding down"
}'
```
The response is the full vendor object (same shape as [Retrieve a vendor](#vendor-object)).
### Error responses
| Status | Body | When |
| - | - | - |
| 400 | `{"detail": {"code": "invalid_update", "message": "..."}}` | Update rejected (for example, an invalid reference ID). |
| 404 | `{"detail": {"code": "vendor_not_found", "message": "Vendor not found."}}` | `vendor_id` not found / not in org. |
| 422 | Standard validation error | Body failed schema validation. |
## The vendor fact sheet
The **fact sheet** is AI-generated company intelligence about a vendor: company profile, products, public perception, financials, leadership, compliance/legal posture, and security posture. Coverbase assembles it from public sources; in the dashboard it powers the vendor "Fact Sheet" tab and its PDF export. These two endpoints let you read that data and trigger a regeneration programmatically.
Generation is **asynchronous**. Trigger it with the refresh endpoint, then poll the fact sheet endpoint until `status` is `"completed"`.
| `status` | Meaning |
| - | - |
| `null` | Never generated. Call the refresh endpoint to populate it. |
| `"pending"` | Generation is in progress. |
| `"completed"` | The most recent generation run finished successfully. |
| `"failed"` | The most recent generation run failed. Trigger another refresh to retry. |
### Retrieve a vendor's fact sheet
`GET /v1/vendors/{vendor_id}/fact-sheet`
Returns the current fact sheet for a vendor. A vendor that has never had a fact sheet generated returns `200` with `status: null` and every section `null`; it is **not** a `404`.
#### Path parameters
The vendor ID (`cbvndr_...`).
#### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/fact-sheet" \
-H "Authorization: Bearer ak_live_xxx"
```
#### Example response
`200 OK`:
```json theme={null}
{
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"entity_id": "cbenty_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"status": "completed",
"progress": ["company profile", "products", "security posture"],
"generated_at": 1746575800,
"company_profile": {
"name": "ACME_Sup_Test1",
"website": "https://supplier1.example.com",
"industry": "Customer support software",
"hq_location": "San Francisco, CA",
"founded_year": 2014,
"description": "Enterprise customer support tooling provider"
},
"products": { "products": [{ "name": "Helpdesk", "description": "Ticketing platform" }] },
"public_perception": { "news_mentions": [], "competitors": [] },
"financials": {
"public_private": "private",
"market_cap_usd": null,
"financial_health": {
"scorecard": {
"score": 68,
"band": "low",
"confidence_tier": "C",
"as_of": "2026-08-12",
"pillars": {
"capital_position": {
"score": 50,
"weight": 0.25,
"contributions": [
{
"label_key": "current_ratio",
"score": 62,
"weight": 0.5,
"value": 1.82,
"unit": "ratio",
"detail_key": null,
"peer_ranked": true,
"as_of": "2026-03-31"
},
{
"label_key": "registration_status",
"score": 50,
"weight": 0.5,
"value": null,
"unit": "categorical",
"detail_key": "unknown",
"peer_ranked": false,
"as_of": null
}
]
}
},
"provenance": { "edgar": "2026-03-31" },
"unavailable_sources": ["pitchbook"]
},
"history": [{ "as_of": "2026-05-12", "score": 65, "band": "low", "confidence_tier": "C" }]
}
},
"people": { "leadership": [{ "name": "Jordan Lee", "title": "CEO" }] },
"compliance_legal": { "legal_actions": [] },
"security_posture": {
"trust_center_url": "https://trust.supplier1.example.com",
"security_incidents": [],
"external_intelligence": {
"domain": "supplier1.example.com",
"generated_at": 1746575800,
"overall_score": 84,
"overall_grade": "B",
"predictive_index": 12,
"factor_scores": [
{
"factor": "email_security",
"score": 45,
"grade": "F",
"data_available": true,
"weight": 0.12,
"findings": [
{
"code": "dmarc_policy_none",
"severity": "high",
"subject": "supplier1.example.com",
"detail": "p=none",
"penalty": 25,
"first_seen": "2026-01-04",
"last_seen": "2026-08-12"
},
{
"code": "dkim_weak_key",
"severity": "moderate",
"subject": "selector1",
"detail": "1024-bit",
"penalty": 15,
"first_seen": "2026-08-12",
"last_seen": "2026-08-12"
}
]
},
{
"factor": "tls_configuration",
"score": 100,
"grade": "A",
"data_available": false,
"weight": 0.1,
"findings": []
}
]
}
}
}
```
**Branch on `data_available` before you read `score`.** The second factor in that example was not measured on this run (the probe reached no conclusion), so it was excluded from `overall_score` entirely. But it still serializes as `score: 100`, `grade: "A"`, with its normal `weight`, because a factor that took no deductions starts at 100.
An integration that renders `factor_scores` without checking `data_available` will show an unmeasured factor as a perfect one. Treat `data_available: false` as "no data", regardless of what `score`, `grade`, and `weight` say.
#### Fact sheet object
The vendor ID (`cbvndr_...`).ID of the underlying entity that holds the fact sheet data. `null` if the vendor is not yet linked to an entity.Generation status: `null`, `"pending"`, `"completed"`, or `"failed"` (see the [status table](#the-vendor-fact-sheet) above).Section names completed so far in the in-progress / most recent run. Empty array if none.Unix timestamp (seconds) the fact sheet was last updated. `null` if never generated.Company profile (name, website, industry, HQ, founding year, headcount, revenue, etc.). Includes `registry_validation`, the validated corporate identity, with a citation per contributing register. `null` until generated.Known products and offerings. `null` until generated.News mentions, third-party reviews (BBB, Trustpilot, CFPB), and competitors. `null` until generated.Public/private status, market cap, ticker/exchange, funding, and transactions. Includes `financial_health` (the Coverbase Financial Health Score) when your organization has that feature enabled. `null` until generated.Leadership and headcount estimate. `null` until generated.Legal actions, enforcement actions, and data-privacy certifications. `null` until generated.Trust center URL, security contact, and known security incidents. Includes `external_intelligence` (the measured outside-in security rating) when your organization has that feature enabled. `null` until generated.
Section objects are best-effort and their internal shape may evolve as Coverbase improves enrichment. Treat the presence of each field defensively; any individual section can be `null` even when `status` is `"completed"` if no data was found for it.
#### Vendor intelligence sections
Three sections carry outside-in intelligence measured from registries of record and from the vendor's own infrastructure, rather than produced by a language model. All three cite their sources. See [Vendor Intelligence](/products/vendor-intelligence), [Financial Health Score](/products/financial-health-score), and [Security Intelligence](/products/security-intelligence) for what each field means.
The Financial Health Score and the measured security rating are optional features, enabled per organization. Write your integration to treat `financials.financial_health` and `security_posture.external_intelligence` as optional. `financial_health` is `null` for an organization that does not have the score enabled. `external_intelligence` is present for every organization once generated, but without the measured rating it scores only the seven original factors. Any section can be `null` even when `status` is `"completed"`.
Validated corporate identity from GLEIF, OpenCorporates, and SEC EDGAR: `official_name`, `registration_status`, `jurisdiction`, `incorporation_date`, addresses, and the identifiers `lei`, `duns`, `company_number`, and `cik`. `is_validated` is `true` only when a register matched with high confidence; `match_decision` and `match_confidence` expose the match quality. `sources` carries one entry per contributing register with its `identifier` and a `url` to the record.
Present for every organization. `null` until a lookup has run.
The Coverbase Financial Health Score. `scorecard` holds `score` (0-100), `band` (the risk band, from `very_high` risk below 20 to `very_low` risk at 80 and above), `confidence_tier` (`A`, `B`, or `C`), `as_of`, the `pillars` breakdown (an object keyed by pillar: `financial_core`, `capital_position`, `momentum`, `adverse_events`, `corporate_standing`), `vitals`, `peer_group` and `peer_percentile`, `events`, `overrides_applied`, `provenance` (source → as-of date), and `unavailable_sources`. `history` carries prior scores for trend.
Returned only when your organization has the Financial Health Score enabled; `null` otherwise.
The individual inputs behind a pillar score, ordered by weighted shortfall so the input that cost the most comes first. Each entry carries:
* `label_key`: the feature identifier (for example `operating_margin`, `registration_status`), or the adverse-event type
* `score`: what this input scored, 0-100
* `weight`: how heavily it counted within the pillar
* `value` and `unit`: the measured figure and its unit (`percent`, `ratio`, `months`, `years`, `usd`, `days_overdue`, or `categorical`)
* `detail_key`: the category behind a non-numeric input (`unknown`, `dissolved`, `down`). **When this is present, `value` is not a measurement.** A `score` of 50 with `detail_key: "unknown"` means the input could not be determined, not that it was measured as mediocre, so render the two cases differently
* `peer_ranked`: `false` means the score came from an absolute curve rather than a peer percentile. This is the single most important caveat on any individual number
* `as_of`: the date this input's value was true, which is not the date of the refresh
`label_key` and `detail_key` are open sets: new identifiers appear as sources are added, so map unknown keys to a readable fallback rather than failing.
Scores are only directly comparable within the same `confidence_tier`. Tier A is computed from filed financial statements; Tier C is inferred from funding, headcount, and corporate-standing signals. Do not rank vendors across tiers on `score` alone.
The measured outside-in security rating, assembled by querying the vendor's own public infrastructure. Top-level fields: `domain` (the domain that was rated), `generated_at` (unix timestamp), `overall_score` (0-100), `overall_grade` (`A` through `F`), `predictive_index` (0-100 likelihood of imminent exploitation), `factor_scores`, and the raw evidence blocks: `vulnerability_findings`, `exposed_services`, `breach_exposures`, `email_authentication`, `web_headers`, `tls_certificate`, `dns_health`, `web_reputation`.
Present for every organization once the security posture has been generated. Without the measured security rating, `factor_scores` covers only the seven original factors (see below).
Ranked next steps derived from the profile when it is read, most urgent first. Each carries a `code` (for example `kev_exploited`, `dmarc_not_enforcing`), a `priority` of `urgent`, `soon` or `routine`, a `count`, the `subjects` it rests on (CVE ids, hosts, domains), and the `factor` it relates to. Empty when no rule fired.
What this scan found that the previous one did not: `previous_as_of`, `previous_score`, `score_delta`, `factor_deltas`, `new_findings`, `resolved_findings`, `new_vulnerabilities`, `resolved_vulnerabilities`, `new_assets` and `departed_assets`. `null` on a first scan and on a profile stored before the comparison existed.
One entry per scored factor. `factor` is one of `patching_cadence`, `network_security`, `email_security`, `tls_configuration`, `web_application_headers`, `dns_health`, `leaked_information`, `ip_reputation`, `application_security`, `web_reputation`, `domain_squatting`. `score` is 0-100, `grade` is `A` through `F`, and `weight` is the absolute weight the factor carried in `overall_score`.
`data_available` is the field to branch on, and the one most likely to bite an integration. When it is `false`, the factor could not be measured on this run and was **excluded from `overall_score`**, but it still carries `score: 100`, `grade: "A"`, and its normal `weight`, because a factor that took no deductions never left its starting value. Read `data_available` first and treat `false` as "no data"; rendering or alerting on `score` without that check turns an unmeasured factor into a perfect one.
Only factors that were scored appear in the array. An organization without the measured security rating enabled gets the seven original factors and no entries for `email_security`, `tls_configuration`, `web_application_headers`, or `domain_squatting` at all.
`findings` carries the structured evidence (below); `drivers` carries the same evidence pre-rendered as English sentences, intended for prompt context rather than display.
The observed facts behind a factor's score, structured so they can be localized:
* `code`: the finding identifier, which selects the sentence (`dmarc_policy_none`, `dkim_weak_key`, `hsts_missing`, `cookie_not_secure`, ...)
* `severity`: `critical`, `high`, `moderate`, `low`, or `info`
* `subject`: what the finding is about, such as a host, a DKIM selector, a cookie name, or a CVE
* `detail`: the observed value, rendered verbatim in every locale (`p=none`, `1024-bit`, `TLSv1.0`)
* `penalty`: points this finding cost its factor
* `evidence_url`: a link to the record, where one exists
* `first_seen` / `last_seen`: ISO-8601 dates carried across refreshes. `first_seen` is how long the finding has stood open, which is often more informative than the finding itself
`code` is an open set and grows as probes are added. Map an unrecognized code to `subject` and `detail`, which are always human-readable, rather than dropping the finding.
A clean `overall_grade` is not evidence of good internal security. Every input is visible from outside the vendor's perimeter and says nothing about access control, key management, secure development, or incident response. Use it to prioritize, not to certify.
Enabling the measured security rating changes `overall_score` for existing vendors: the rating goes from seven factors to eleven, with new weights. If you store or alert on `overall_score`, expect a one-time shift when the feature is turned on for your organization.
#### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "vendor_not_found", "message": "Vendor not found."}}` | `vendor_id` does not exist or is not in the API key's org. |
### Refresh a vendor's fact sheet
`POST /v1/vendors/{vendor_id}/fact-sheet/refresh`
Queues a (re)generation of the vendor's fact sheet and returns immediately with `202 Accepted` and `status: "pending"`. Existing fact sheet data is cleared at the start of the run, so a `GET` made right after a refresh reflects the `pending` state. Poll the [fact sheet endpoint](#retrieve-a-vendors-fact-sheet) until `status` is `"completed"`.
This endpoint is not idempotent; each call queues a fresh generation run.
#### Path parameters
The vendor ID (`cbvndr_...`).
#### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162/fact-sheet/refresh" \
-H "Authorization: Bearer ak_live_xxx"
```
#### Example response
`202 Accepted`:
```json theme={null}
{
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"entity_id": "cbenty_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"status": "pending",
"message": "Fact sheet regeneration has been queued."
}
```
The vendor ID (`cbvndr_...`).ID of the underlying entity, or `null` when the vendor is being linked to one for the first time as part of this run.Always `"pending"` on a successful enqueue.Human-readable acknowledgement.
#### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "vendor_not_found", "message": "Vendor not found."}}` | `vendor_id` does not exist or is not in the API key's org. |
# Webhooks API
Source: https://docs.coverbase.com/api-reference/webhooks
Register, list, update, delete, and test webhook subscriptions.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Webhooks API manages webhook subscription records and can send a manual test delivery to a registered endpoint. For the delivery format, fan-out, signature verification, and the event catalog, see the [Webhooks](/integrations/webhooks) guide. For the audit trail of every attempt, see [Webhook delivery history](/integrations/webhook-deliveries).
All endpoints are org-scoped to the API key. See [API conventions](/conventions) for authentication and the error envelope.
An API key can call every endpoint here. With a dashboard session, only an **Admin** can register, update, test or delete a webhook; anyone else gets `403 forbidden`. Listing webhooks and reading delivery history stay open to Members.
## Register a webhook
`POST /v1/webhooks`
Creates a webhook subscription. Returns `201 Created`.
### Request body
The public HTTPS endpoint Coverbase will POST to. Rejected with `400 invalid_url` if it is not HTTPS, carries credentials, uses a non-standard port, or resolves to a private / loopback / link-local / metadata address. See [URL restrictions](/integrations/webhooks#url-restrictions).
Event type strings to subscribe to. **Strictly validated** against the [event catalog](/integrations/webhooks#event-catalog); any value not in the catalog fails with `422 invalid_event_types`. Use the exact, case-sensitive values (for example, `Vendor.Created`).
Shared secret used to sign deliveries (HMAC-SHA256). **Must be at least 16 characters.** Write-only; it is never returned in any response.
Optional human-readable label.
Defaults to `true`. When `false`, the subscription is created in a disabled state.
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/webhooks" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.example.com/coverbase",
"events": ["Vendor.Created", "Vendor.Updated", "Assessment.Created"],
"secret": "whsec_a1b2c3d4e5f6a7b8c9d0e1f2",
"description": "Primary GRC integration"
}'
```
```python Python theme={null}
import os
import secrets
import requests
API_KEY = os.environ["COVERBASE_API_KEY"]
BASE_URL = "https://api.coverbase.app"
webhook_secret = f"whsec_{secrets.token_hex(24)}" # >= 16 chars
resp = requests.post(
f"{BASE_URL}/v1/webhooks",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
},
json={
"url": "https://hooks.example.com/coverbase",
"events": ["Vendor.Created", "Vendor.Updated", "Assessment.Created"],
"secret": webhook_secret,
"description": "Primary GRC integration",
},
timeout=30,
)
resp.raise_for_status()
print(resp.json())
```
### Example response
`201 Created`:
```json theme={null}
{
"id": "cbwh_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9",
"url": "https://hooks.example.com/coverbase",
"events": ["Vendor.Created", "Vendor.Updated", "Assessment.Created"],
"description": "Primary GRC integration",
"enabled": true,
"created_at": 1746576000,
"last_delivery_status": null,
"delivery_success_rate": null,
"delivery_count": 0
}
```
The `secret` is never returned after creation. Store it at registration time. If lost, set a new one via the update endpoint.
### Response fields
Webhook ID (`cbwh_...`).
The registered HTTPS endpoint.
Subscribed event strings.
The label, if set.
`true` when the subscription is active.
Unix timestamp (seconds) when the webhook was created.
Status of the most recent recorded delivery attempt (one of `delivered`, `timeout`, `error`), or `null` if there are no recorded deliveries yet.
Fraction of recorded attempts that were `delivered`, `0`-`1` (rounded to 4 dp). `null` when there are no recorded deliveries.
Total recorded delivery attempts for this webhook. `0` when none.
See [Webhook delivery history](/integrations/webhook-deliveries) for the per-attempt records behind these aggregates.
### Error responses
Validation is applied in this order: `secret`, then `url`, then `events`.
| Status | Body | When |
| - | - | - |
| 400 | `{"detail": {"code": "weak_secret", "message": "Secret must be at least 16 characters."}}` | `secret` is shorter than 16 characters. Checked first. |
| 400 | `{"detail": {"code": "invalid_url", "message": "Webhook URL must be HTTPS and must not target a private, link-local, loopback, or metadata address."}}` | `url` is not a public HTTPS endpoint. See [URL restrictions](/integrations/webhooks#url-restrictions). |
| 422 | `{"detail": {"code": "invalid_event_types", "message": "Unsupported event type(s): ..."}}` | `events` contains a value not in the [event catalog](/integrations/webhooks#event-catalog). |
| 422 | Standard validation error | Required fields missing or wrong type. See [API conventions](/conventions#validation-errors). |
## List webhooks
`GET /v1/webhooks`
Returns all (non-archived) webhook subscriptions for the org, each including its delivery-health aggregates.
### Example response
```json theme={null}
{
"data": [
{
"id": "cbwh_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9",
"url": "https://hooks.example.com/coverbase",
"events": ["Vendor.Created", "Assessment.Created"],
"description": "Primary GRC integration",
"enabled": true,
"created_at": 1746576000,
"last_delivery_status": "delivered",
"delivery_success_rate": 0.9821,
"delivery_count": 56
}
]
}
```
Each item has the same shape as the [create response](#response-fields), including `last_delivery_status`, `delivery_success_rate`, and `delivery_count`.
## Update a webhook
`PATCH /v1/webhooks/{webhook_id}`
Updates a webhook subscription. Only the fields you include are changed; omitted fields, and `null` for any field except `description`, are left unchanged. Returns the updated webhook (same shape as the create response).
### Request body
New endpoint. If provided, it must pass the same [URL restrictions](/integrations/webhooks#url-restrictions) as on create.
Replace the subscribed event list. Strictly validated against the [event catalog](/integrations/webhooks#event-catalog); an unsupported value fails with `422 invalid_event_types`.
Rotate the signing secret. If provided, must be at least 16 characters.
Update the label. Send `null` to clear it.
Enable or disable the subscription.
### Example requests
```bash Update events theme={null}
curl -X PATCH "https://api.coverbase.app/v1/webhooks/cbwh_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "events": ["Vendor.Created", "Vendor.Updated", "Assessment.Updated"] }'
```
```bash Rotate the secret theme={null}
curl -X PATCH "https://api.coverbase.app/v1/webhooks/cbwh_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "secret": "whsec_newsecretvalueatleast16" }'
```
### Error responses
| Status | Body | When |
| - | - | - |
| 400 | `{"detail": {"code": "weak_secret", "message": "..."}}` | A new `secret` shorter than 16 characters was supplied. |
| 400 | `{"detail": {"code": "invalid_url", "message": "Webhook URL must be HTTPS and must not target a private, link-local, loopback, or metadata address."}}` | A new `url` that is not a public HTTPS endpoint was supplied. |
| 422 | `{"detail": {"code": "invalid_event_types", "message": "Unsupported event type(s): ..."}}` | A new `events` value is not in the [event catalog](/integrations/webhooks#event-catalog). |
| 404 | `{"detail": {"code": "webhook_not_found", "message": "Webhook not found."}}` | The `webhook_id` does not exist or is not in the API key's org. |
## Delete a webhook
`DELETE /v1/webhooks/{webhook_id}`
Archives (soft-deletes) the webhook subscription. Returns `204 No Content`.
```bash cURL theme={null}
curl -X DELETE "https://api.coverbase.app/v1/webhooks/cbwh_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9" \
-H "Authorization: Bearer ak_live_xxx"
```
| Status | Body | When |
| - | - | - |
| 204 | *(empty)* | Archived successfully. |
| 404 | `{"detail": {"code": "webhook_not_found", "message": "Webhook not found."}}` | The `webhook_id` does not exist or is not in the API key's org. |
## Test a webhook
`POST /v1/webhooks/{webhook_id}/test`
Enqueues a test delivery to the webhook's URL. The delivery is dispatched asynchronously, so the response confirms the test was **enqueued**; it does not contain the receiver's HTTP status.
### Request body
Event type string to send in the test delivery. Unlike subscription `events`, this is **not** validated against the catalog; any string is accepted, including `webhook.test`.
Optional. The object delivered as the envelope's `data`. Defaults to `{"test": true}`.
### Example request
```bash Custom payload theme={null}
curl -X POST "https://api.coverbase.app/v1/webhooks/cbwh_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9/test" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "event_type": "Vendor.Created", "payload": { "vendor_id": "cbvndr_demo" } }'
```
```bash Default payload theme={null}
curl -X POST "https://api.coverbase.app/v1/webhooks/cbwh_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9/test" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "event_type": "webhook.test" }'
```
### Example response
```json theme={null}
{
"event_id": "cbevt_test_8b3c1a4d9e7f2c5b6a8d1e3f9c7b4a2e",
"delivered": true,
"response_status": null,
"response_time_ms": null,
"attempted_at": 1746576180
}
```
`delivered` reflects that the test was **enqueued**, not that the receiver accepted it. `response_status` and `response_time_ms` are always `null` on this response because delivery happens out of band. The actual attempt (and the receiver's real status) is recorded in [delivery history](/integrations/webhook-deliveries). The delivered envelope's `data` is your `payload` (default `{"test": true}`).
### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "webhook_not_found", "message": "Webhook not found."}}` | The `webhook_id` does not exist or is not in the API key's org. |
## List delivery attempts
`GET /v1/webhooks/{webhook_id}/deliveries`
Returns the paginated delivery history for a webhook, newest first. Full request/response schema, query parameters, status values, and pagination are documented on the [Webhook delivery history](/integrations/webhook-deliveries) page.
```bash cURL theme={null}
curl "https://api.coverbase.app/v1/webhooks/cbwh_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9/deliveries?limit=50&offset=0" \
-H "Authorization: Bearer ak_live_xxx"
```
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "webhook_not_found", "message": "Webhook not found."}}` | The `webhook_id` does not exist or is not in the API key's org. |
## Dark web exposure payload
`DarkWebExposure.Created` and `DarkWebExposure.Updated` deliveries carry the exposure's facts inside `data`, so a SIEM or SOAR playbook can act without calling back. The envelope, signing and retries are the same as every other event (see [Webhooks](/integrations/webhooks)). `DarkWebExposure.Deleted` carries only `dark_web_exposure_id`.
The payload never includes the exposure's summary, its source details, a capture, or an unmasked identifier.
```json Example data for DarkWebExposure.Created theme={null}
{
"event_type": "DarkWebExposure.Created",
"dark_web_exposure_id": "cbdwexp_01J9Q3",
"id": "cbdwexp_01J9Q3",
"category": "routing_number",
"category_label": "Routing number",
"severity": "critical",
"status": "new",
"subject": { "kind": "organization", "vendor_id": null, "vendor_name": null },
"source": "coverbase_crawler",
"channel": "paste_site",
"context": "account_list",
"matched": { "kind": "routing_number", "masked": "•••••7751" },
"item_count": 38,
"title": "Routing number posted with 38 account numbers",
"detected_at": "2026-09-30T19:14:05Z",
"first_seen_at": "2026-09-30T19:14:05Z",
"last_seen_at": "2026-09-30T19:14:05Z",
"ack_due_at": "2026-09-30T23:14:05Z",
"decision_due_at": null,
"case_id": null,
"url": "https://app.coverbase.app/dark-web?exposureId=cbdwexp_01J9Q3"
}
```
| Field | Type | Description |
| - | - | - |
| `id` | string | The exposure id. `dark_web_exposure_id` repeats it for existing integrations. |
| `category` | string | `routing_number`, `payment_card_exposure`, `credential_leak`, `stealer_infection`, `ransomware_victim`, `data_breach`, `brand_impersonation`, `dark_web_mention`, `ai_fraud` or `code_leak`. |
| `category_label` | string | Display label for the category, for example `Card BIN` for `payment_card_exposure`. |
| `severity` | string | `critical`, `high`, `medium`, `low` or `info`. |
| `status` | string | The review status at delivery time, for example `new`, `acknowledged`, `confirmed` or `resolved`. |
| `subject` | object | `kind` is `organization` or `vendor`. `vendor_id` and `vendor_name` are set for a vendor or partner. |
| `source` | string | The feed that found it, for example `coverbase_crawler`, `hibp` or `ransomlook`. |
| `channel` | string or null | Where it was posted, for example `paste_site` or `forum`, when the source reports it. |
| `context` | string or null | For routing numbers and card BINs: `account_list`, `card_list`, `cash_out_method`, `check_sale_mention` or `mention`. |
| `matched` | object | The watched identifier that matched. `kind` is its type; `masked` shows a routing number's last 4 digits, a BIN's first digit and last 2, a mailbox's first character and domain. |
| `item_count` | integer or null | How many accounts, cards or records the post states, when it states a count. |
| `title` | string | The exposure title. |
| `detected_at`, `first_seen_at`, `last_seen_at` | string | ISO 8601 timestamps in UTC. |
| `ack_due_at` | string or null | When the acknowledge clock runs out, counted in your business hours. Null when no clock runs. |
| `decision_due_at` | string or null | When the Legal decision is due, while the exposure is with Legal. |
| `case_id` | string or null | The Legal case the exposure is linked to, if any. |
| `url` | string | A link to the exposure in Coverbase. Opening it requires sign-in. |
| `field_diffs` | object | `DarkWebExposure.Updated` only: the fields that changed, as on every other `.Updated` event. |
To check your parser, open **Configuration**, **Dark Web**, **Alerts** and click **Send test**. Coverbase signs a fictional `DarkWebExposure.Created` payload and sends it to every webhook subscribed to that event.
## Appendix A: cURL quick reference
One block per endpoint, copy-paste ready. Set these once:
```bash Setup theme={null}
export CB="https://api.coverbase.app"
export AK="ak_REPLACE_ME" # dashboard → API keys
export ORG_ID="cborg_REPLACE_ME" # the id field on the org object
A=(-H "Authorization: Bearer $AK" -H "Content-Type: application/json")
```
```bash Create a webhook theme={null}
WH=$(curl -sS -X POST "$CB/v1/webhooks" "${A[@]}" -d '{
"url": "https://hooks.example.com/coverbase",
"events": ["Vendor.Created", "Assessment.Updated"],
"secret": "whsec_at_least_16_chars",
"description": "Prod receiver",
"enabled": true
}' | jq -r .id)
echo "$WH"
# 201 → {id, url, events, description, enabled, created_at,
# last_delivery_status:null, delivery_success_rate:null, delivery_count:0}
```
```bash Validation errors theme={null}
# weak secret → 400 {"detail":{"code":"weak_secret",...}}
curl -sS -X POST "$CB/v1/webhooks" "${A[@]}" \
-d '{"url":"https://hooks.example.com/x","events":["Vendor.Created"],"secret":"short"}'
# SSRF-blocked / non-HTTPS URL → 400 {"detail":{"code":"invalid_url",...}}
curl -sS -X POST "$CB/v1/webhooks" "${A[@]}" \
-d '{"url":"https://169.254.169.254/latest/meta-data/","events":["Vendor.Created"],"secret":"whsec_at_least_16_chars"}'
curl -sS -X POST "$CB/v1/webhooks" "${A[@]}" \
-d '{"url":"http://hooks.example.com/x","events":["Vendor.Created"],"secret":"whsec_at_least_16_chars"}'
# unsupported event type → 422 {"detail":{"code":"invalid_event_types",...}}
curl -sS -X POST "$CB/v1/webhooks" "${A[@]}" \
-d '{"url":"https://hooks.example.com/x","events":["vendor.created"],"secret":"whsec_at_least_16_chars"}'
```
```bash List webhooks (with delivery health) theme={null}
curl -sS "$CB/v1/webhooks" "${A[@]}" | jq '.data[] |
{id, url, enabled, last_delivery_status, delivery_success_rate, delivery_count}'
```
```bash Update a webhook theme={null}
curl -sS -X PATCH "$CB/v1/webhooks/$WH" "${A[@]}" \
-d '{"events":["Vendor.Created","Vendor.Updated"],"enabled":false}'
# invalid event on update → 422 invalid_event_types
curl -sS -X PATCH "$CB/v1/webhooks/$WH" "${A[@]}" -d '{"events":["not.real"]}'
```
```bash Send a test delivery theme={null}
curl -sS -X POST "$CB/v1/webhooks/$WH/test" "${A[@]}" \
-d '{"event_type":"Vendor.Created","payload":{"vendor_id":"cbvndr_demo"}}'
# default payload form:
curl -sS -X POST "$CB/v1/webhooks/$WH/test" "${A[@]}" -d '{"event_type":"webhook.test"}'
# → {event_id, delivered, response_status, response_time_ms, attempted_at}
```
```bash Delivery history (paginated, newest first) theme={null}
curl -sS "$CB/v1/webhooks/$WH/deliveries?limit=50&offset=0" "${A[@]}" | jq '{
total, limit, offset,
data: [.data[] | {event_type, status, response_status,
response_time_ms, error, attempted_at}]
}'
# next page:
curl -sS "$CB/v1/webhooks/$WH/deliveries?limit=50&offset=50" "${A[@]}"
# unknown id → 404 {"detail":{"code":"webhook_not_found",...}}
curl -sS "$CB/v1/webhooks/cbwh_nope/deliveries" "${A[@]}"
```
```bash Delete a webhook theme={null}
curl -sS -o /dev/null -w '%{http_code}\n' -X DELETE "$CB/v1/webhooks/$WH" "${A[@]}" # 204
```
```bash Org-level API IP allowlist theme={null}
# Changing the allowlist and whoami take an admin's dashboard session token, not an ak_ key:
J=(-H "Authorization: Bearer $ADMIN_JWT" -H "Content-Type: application/json")
# Configure (CIDRs validated server-side; invalid → 422):
curl -sS -X POST "$CB/v1/org/$ORG_ID" "${J[@]}" \
-d '{"api_ip_allowlist":["203.0.113.0/24","198.51.100.7/32"]}'
curl -sS -X POST "$CB/v1/org/$ORG_ID" "${J[@]}" \
-d '{"api_ip_allowlist":["not-a-cidr"]}' # → 422
# Read back with the API key (org object now returns api_ip_allowlist):
curl -sS "$CB/v1/org/$ORG_ID" "${A[@]}" | jq .api_ip_allowlist
# Once a non-empty allowlist is set, a call from an IP outside the CIDRs → 403:
# {"detail":{"code":"ip_not_allowed","message":"..."}}
# Clear (unrestricted again):
curl -sS -X POST "$CB/v1/org/$ORG_ID" "${J[@]}" -d '{"api_ip_allowlist":[]}'
# Find the IP the API sees for the caller (same value the allowlist evaluates):
curl -sS "$CB/v1/whoami/ip" "${J[@]}" # → {"client_ip":"203.0.113.42"}
```
For receiver-side signature verification (Python and Node), see [Webhooks → Signature verification](/integrations/webhooks#signature-verification).
# Workflows API
Source: https://docs.coverbase.com/api-reference/workflows
Invoke a named workflow and poll its run state.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Workflows API lets external systems start a workflow by name with an input payload, schedule one for later, and read the state of a run.
All endpoints are org-scoped to the API key. See [API conventions](/conventions) for authentication, IDs, timestamps, idempotency, and the error envelope.
## Run a workflow
`POST /v1/workflows/{workflow_name}/run`
Starts a new run of the named workflow. Returns `201 Created`. The `workflow_name` path segment is matched against the workflow definition's `name` for your org.
The run row is created and committed, and the commit emits a `WorkflowRun.Created` event to the workflow engine. The engine runs the definition's entrypoint components that subscribe to that event, which is how a directly runnable workflow starts; an event-driven workflow starts from its own domain events instead. The response returns as soon as the run is created; poll [Get a workflow run](#get-a-workflow-run) for progress.
### Path parameters
The name of the workflow as configured for your org.
### Request body
Workflow input parameters. Optional; defaults to `{}`. The value is stored and echoed back on the response. Record IDs under the well-known keys (`vendor_id`, `service_id`, `assessment_id`, `engagement_id`, `contract_id`, `finding_id`, `vendor_document_id`, `questionnaire_response_id`, `intake_session_id`, `procurement_id`, `review_id`, `eval_id`, `portal_id`, `work_queue_item_id`, `radar_event_id`, `radar_case_id`) tell the workflow's actions which record to act on, and `custom_fields` passes custom field values to them. Any other key is stored as given. A number under a well-known key is converted to a string, and `null` values are dropped.
### Headers
`Bearer ak_...`
Optional. If the same key is sent again within 24 hours for this endpoint, the original response is returned and no new run is started. See [Idempotency](/conventions#idempotency).
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/workflows/quarterly-privacy-sweep/run" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Idempotency-Key: privacy-sweep-2026-q2" \
-H "Content-Type: application/json" \
-d '{
"input": {
"vendor_filter": { "tags": ["processes_pii"] },
"due_date": "2026-06-30"
}
}'
```
```python Python theme={null}
import os
import requests
API_KEY = os.environ["COVERBASE_API_KEY"]
BASE_URL = "https://api.coverbase.app"
resp = requests.post(
f"{BASE_URL}/v1/workflows/quarterly-privacy-sweep/run",
headers={
"Authorization": f"Bearer {API_KEY}",
"Idempotency-Key": "privacy-sweep-2026-q2",
"Content-Type": "application/json",
},
json={"input": {"vendor_filter": {"tags": ["processes_pii"]}, "due_date": "2026-06-30"}},
timeout=30,
)
resp.raise_for_status()
print(resp.json())
```
### Example response
`201 Created`:
```json theme={null}
{
"workflow_run_id": "cbwr_a8f2c19e3d4b5e6f7a8b9c0d1e2f3a4b",
"workflow_name": "quarterly-privacy-sweep",
"status": "started",
"started_at": 1746576000,
"input": {
"vendor_filter": { "tags": ["processes_pii"] },
"due_date": "2026-06-30"
}
}
```
### Response fields
Identifier for this run (`cbwr_...`). Use it with the get-run endpoint.
The resolved workflow definition name.
Run status. One of: `started`, `completed`, `canceled`, `failed`. A new run is `started`.
Unix timestamp (seconds) when the run was created.
Echoes the input sent in the request.
### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "workflow_not_found", "message": "Workflow '...' not found."}}` | No workflow with that name exists for the org. |
| 409 | `{"detail": {"code": "workflow_disabled", "message": "Workflow '...' is disabled."}}` | The workflow exists but is not enabled. |
| 422 | Standard validation error | The request body failed schema validation. See [API conventions](/conventions#validation-errors). |
## Schedule a workflow run
`POST /v1/workflows/{workflow_name}/schedule`
Schedules a run of a directly runnable workflow for a future time instead of starting it now. Returns `201 Created` with the schedule. When the time comes, the run starts as if you had called [Run a workflow](#run-a-workflow) with the same `input`.
### Request body
When to run, as a Unix timestamp in seconds. Must be in the future.
Workflow input, as for [Run a workflow](#run-a-workflow). Defaults to `{}`.
The endpoint honors `Idempotency-Key`. See [Idempotency](/conventions#idempotency).
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/workflows/quarterly-privacy-sweep/schedule" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "scheduled_for": 1767225600, "input": { "vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162" } }'
```
### Response fields
The schedule carries `id`, `workflow_definition_id` (`cbwd_...`), `scheduled_for`, `fired_at` and `canceled_at` (both `null` until the schedule fires or is canceled), `cancel_reason`, `payload` (the input pinned at schedule time), and `updated_at`. The `scheduling_*` fields are `null` for schedules created through this endpoint.
### Error responses
| Status | Body | When |
| - | - | - |
| 400 | `{"detail": {"code": "workflow_not_direct_runnable", "message": "..."}}` | The workflow starts from domain events, not a direct run. |
| 400 | `{"detail": {"code": "scheduled_for_in_past", "message": "..."}}` | `scheduled_for` is not in the future. |
| 404 | `{"detail": {"code": "workflow_not_found", "message": "Workflow '...' not found."}}` | No workflow with that name exists for the org. |
| 409 | `{"detail": {"code": "workflow_archived", "message": "Workflow '...' is archived."}}` | The workflow is archived. |
| 409 | `{"detail": {"code": "workflow_disabled", "message": "Workflow '...' is disabled."}}` | The workflow is not enabled. |
## Get a workflow run
`GET /v1/workflows/runs/{workflow_run_id}`
Returns the current state of a workflow run.
### Path parameters
The run ID (`cbwr_...`).
### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/workflows/runs/cbwr_a8f2c19e3d4b5e6f7a8b9c0d1e2f3a4b" \
-H "Authorization: Bearer ak_live_xxx"
```
### Example response
```json theme={null}
{
"workflow_run_id": "cbwr_a8f2c19e3d4b5e6f7a8b9c0d1e2f3a4b",
"workflow_name": "quarterly-privacy-sweep",
"workflow_definition_id": "cbwd_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
"status": "completed",
"started_at": 1746576000,
"completed_at": 1746579600,
"steps": [
{
"step_id": "cbwrs_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
"component_id": "cbwc_9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d",
"component_name": "Send questionnaire",
"action_type": "send_questionnaire",
"status": "success",
"message": null,
"artifacts": [
{ "artifact_type": "vendor", "id": "cbvndr_e448ba62882143f3ba0c140bb2e30162", "role": "trigger" },
{ "artifact_type": "questionnaire_response", "id": "cbqsrw_2d5e8f1a4b7c0d3e6f9a2b5c8d1e4f7a", "role": "result" }
],
"created_at": 1746576540,
"updated_at": 1746576600
}
]
}
```
### Response fields
The run ID (`cbwr_...`).
The workflow definition name, or `null` if the definition could not be resolved.
The workflow definition ID (`cbwd_...`).
Run status. One of: `started`, `completed`, `canceled`, `failed`.
Unix timestamp (seconds) when the run was created.
Unix timestamp (seconds) when the run finished. Populated only when `status` is `completed`, `failed`, or `canceled`; otherwise `null`.
Executed steps for this run (empty array if none yet). Each step records both the component that ran and the outcome of that component's action. Each step has:
The run-step ID (`cbwrs_...`).The workflow component this step ran.The component's display name.The component's action type (for example, `send_questionnaire`), when available.Action outcome. One of `success`, `failed`, `skipped`, or `null` if the engine has not yet recorded a result for this step.Optional human-readable explanation. Set on failure to surface the error; set on `skipped` to explain why; usually `null` on success.
Entities the step consumed or produced. Each entry has `artifact_type` (the canonical target type, for example, `vendor`, `assessment`, `questionnaire_response`), `id` (the entity ID), and `role` (`trigger` for entities that fed into the step; `result` for entities the step created or modified).
Unix timestamp (seconds) when the step was recorded.Unix timestamp (seconds) of the step's last update.
Poll this endpoint until `status` is terminal (`completed`, `canceled`, or `failed`); `steps[]` grows as the engine progresses, and each step's `status` and `artifacts` reflect what that stage did.
### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "workflow_run_not_found", "message": "Workflow run not found."}}` | The `workflow_run_id` does not exist or is not in the API key's org. |
## List workflow runs
`GET /v1/workflows/runs`
Returns workflow runs for the org, newest first. Use this when you don't already know the run ID; for example, to discover runs created by other systems or by Coverbase's internal automations, or to reconcile run history against an external scheduler.
### Query parameters
Filter to runs of a specific workflow definition by name. Returns `404 workflow_not_found` if no workflow with that name exists for the org.
Filter by run status. Repeat to include multiple statuses, for example, `?status=started&status=failed`. Valid values: `started`, `completed`, `canceled`, `failed`.
Unix timestamp (seconds). Include only runs created at or after this time.
Unix timestamp (seconds). Include only runs created at or before this time.
Page size. Min `1`, max `500`.
Pagination offset.
### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/workflows/runs?workflow_name=quarterly-privacy-sweep&status=failed&limit=20" \
-H "Authorization: Bearer ak_live_xxx"
```
### Example response
```json theme={null}
{
"data": [
{
"workflow_run_id": "cbwr_a8f2c19e3d4b5e6f7a8b9c0d1e2f3a4b",
"workflow_name": "quarterly-privacy-sweep",
"workflow_definition_id": "cbwd_1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
"status": "failed",
"started_at": 1746576000,
"completed_at": 1746576720,
"step_count": 3
}
],
"total": 1,
"limit": 20,
"offset": 0
}
```
### Response fields
Paginated list of run summaries. Each entry mirrors the keys of [Get a workflow run](#get-a-workflow-run), minus `steps[]` and plus `step_count`. Fetch the full run via `GET /v1/workflows/runs/{workflow_run_id}` when you need per-stage outcomes.
Total number of runs matching the filters (across all pages).
Echoes the requested page size.
Echoes the requested offset.
### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "workflow_not_found", "message": "Workflow '...' not found."}}` | `workflow_name` was supplied but no workflow with that name exists for the org. |
| 422 | Standard validation error | A query parameter failed validation (for example, `limit` out of range, malformed `status`). |
# Zero Touch Assessments API
Source: https://docs.coverbase.com/api-reference/zero-touch-assessments
Launch lightweight, no-outreach triage runs, rank a portfolio by the resulting score, and read a single run's composite and evidence.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A Zero Touch Assessment is a lightweight triage run assembled entirely from open-source research, with no document request, no questionnaire and no vendor contact. It produces a single 0-100 **Zero Touch Score** so a portfolio can be ranked before real review effort is spent.
For the concepts behind the score, see [Zero Touch Assessments](/user-guides/zero-touch-assessments).
Every endpoint below is behind the `zero-touch-assessments` module. If it is not enabled for your organization, these routes return `404`. Contact your Coverbase representative to have it turned on.
All endpoints are org-scoped. They are the endpoints the dashboard's Zero Touch pages use, so they take a signed-in user's dashboard session token (a JWT); an `ak_` API key is rejected with `401 Unauthorized role.` Most error bodies carry a free-form `error` key rather than a code. See [API conventions](/conventions) for IDs, timestamps, and the error envelope.
## Launch a run
`POST /v1/zero_touch_assessment`
Starts a Zero Touch Assessment for one vendor.
### Request body
The vendor ID (`cbvndr_...`) to assess.
Restrict the run to specific services. Omit to run against the vendor as a whole.
Switch your organization's Zero Touch scope to this template before launching. Omit to launch against whatever is already configured, which is what a caller with no opinion means.
This is an organization-level setting, not a per-run one. Passing it changes what **every subsequent run** evaluates, including runs launched from the dashboard.
A correction in plain language, up to 2000 characters, applied to the vendor before the run starts. Use it when the vendor record points at the wrong company or website: research reads the vendor's website at launch, so a correction made afterwards does not change what the run read.
### Responses
| Status | Meaning |
| - | - |
| `200` | The run was created. The body is the run summary. |
| `400` | The vendor ID is unknown or belongs to another organization, or `template_key` is not a shipped template. |
| `404` | The module is not enabled. |
| `409` | No Zero Touch control sets are designated for your organization. |
Organizations are provisioned the shipped templates on first use, so a `409` is unusual. It means every template has since been un-designated or archived, which is a deliberate act that provisioning will not undo.
## Launch in bulk
`POST /v1/zero_touch_assessment/bulk`
Starts a run for many vendors in one call. Vendor IDs are deduplicated.
Vendor IDs to assess, from 1 to 200.
Switch your organization's Zero Touch scope to this template before launching, as on a single launch.
**Partial success is the normal outcome and returns `200`.** The response separates the two:
Run summaries for the vendors that launched.
One entry per vendor that could not launch, each with `vendor_id` and `error`.
One archived or unknown vendor in a selection of forty does not cost you the other thirty-nine. Always read `failed`. A `200` does not mean every vendor launched.
## Read a run
`GET /v1/zero_touch_assessment/{assessment_id}`
Returns the single-page result: who the vendor is, what turned up against its name, the composite, the components behind it, control-set coverage, open issues with their evidence, and every source cited.
The researched company profile: `company_name`, `url`, `description`, `industry`, `use_case`, `services`, `hq_location`, and `confidence`, which is how sure the run is it profiled the right company. `null` until the research completes, which happens shortly after launch and independently of the controls.
`critical`, `high`, `moderate`, `low` or `minimal`, with `risk_tier_confidence`, a one-line `risk_tier_reasoning` and the full `risk_tier_detailed_reasoning`.
This is its own scale, not your organization's risk levels. Those are calibrated against a completed questionnaire; this is judged from public evidence. Do not map one onto the other.
The Zero Touch Score, 0-100, higher is healthier. `null` when nothing has resolved yet.
One entry per component (`controls`, `financial_health`, `security`, `registration`, `people`), each with `status` (`scored` / `unavailable` / `disabled`), its own `score`, the `configured_weight` set for your org, and the `weight` it carried.
What the run found against the vendor's name, gathered from adverse media, open watchlist matches and the run's own `ZT-REP-*` controls. Carries an overall `standing`, a one-line `headline`, `finding_count` and `material_count`, a `dimensions` array, and a `findings` array. `null` on a run scored before this section existed, which means the run never assembled one rather than that the vendor is clear.
One entry per dimension (`media_sentiment`, `litigation`, `regulatory`, `executive_conduct`, `association`), each with its `label`, its own `standing`, `finding_count`, `material_count` and a `detail` line.
One entry per reputational matter, ordered material first then by severity. Each carries the `origin` that raised it (`adverse_media`, `screening`, `control`), the `dimension` it is filed under, a `headline` and `summary`, the `subject` it attaches to (`null` for the company itself), a `severity`, an `outcome`, `publisher`, `published_at`, `jurisdiction`, `source_urls`, `is_disputed` and `is_resolved`.
**A dimension nothing searched reads `not_screened`, never `clear`.** The four standings are `adverse`, `watch`, `clear` and `not_screened`. `clear` means something searched and found nothing; `not_screened` means nothing searched, and carries no information about the vendor. `coverage_note` names every unscreened dimension. Do not treat an empty `findings` array as a clean record without reading `dimensions`.
Every place the run drew evidence from, grouped by `kind`: `web`, `registry`, `infrastructure`, `document`.
**A component with no data is excluded from the composite, never counted as zero.** Weights renormalise over whatever resolved, which is why `weight` and `configured_weight` differ. A vendor scored on one component is not comparable to a vendor scored on three, so read `components` before ranking on `composite_score`.
A run that has not finished is scored on the fly, so this endpoint is useful before completion. Only completion and an explicit rescore persist the snapshot.
## Rank a portfolio
`GET /v1/zero_touch_assessment/leaderboard`
Returns one row per vendor, its most recent run, ranked by composite score. Supports `limit`, `offset` and `search`.
Ranking is computed across the whole organization before the page is sliced, so paging through the leaderboard gives a true global ranking. Unscored runs sort last rather than as zero.
## List and choose templates
`GET /v1/zero_touch_assessment/templates`
`POST /v1/zero_touch_assessment/template`
The `GET` returns the shipped templates with their control counts and domains, plus `active_template_key`, the one your runs currently evaluate. It is `null` when your organization runs a control set of its own, or when more than one shipped template is designated; both are states to show rather than resolve arbitrarily.
The `POST` takes `{"template_key": "..."}` and points future runs at that template. It only ever re-designates control sets this module provisioned, so a set designated for you by Coverbase is never disturbed. An unknown key returns `400`; an organization that runs a control set of its own gets `409`.
## Re-source a run's vendor profile
`POST /v1/zero_touch_assessment/{assessment_id}/reprofile`
Re-researches the company behind the run and replaces the profile on it. Separate from re-scoring because they answer different questions: a correction that repoints a run at the right company leaves the score valid while the profile still describes somebody else.
Re-scoring deliberately carries an existing profile forward, so this is the only call that refreshes it.
## Re-score a run
`POST /v1/zero_touch_assessment/{assessment_id}/rescore`
Recomputes the composite against today's inputs and re-applies the configured score push, without re-running the controls. Use this when the financial or security inputs have refreshed, or after changing your scoring configuration.
## Review a run
`POST /v1/zero_touch_assessment/{assessment_id}/review`
Records a decision against a run without changing what it was built on.
`approved`, `escalated`, `archived`, or `note`.
Free text, up to 4000 characters.
Optional. A vendor status (`cbst_...`) to set on the vendor along with the decision. Requires permission to update the vendor.
Escalating records the judgement; it does not launch a full assessment. Archiving takes the run out of the working set and needs permission to archive assessments.
## Correct a run's inputs
`POST /v1/zero_touch_assessment/{assessment_id}/correct`
The correction in plain language, up to 2000 characters.
The instruction is read into a fixed set of correctable fields (the vendor's website and name), applied, and the run re-scored against them. Returns the re-scored run.
An instruction that yields no concrete change still returns `200` and still writes an audit entry with an empty `changes` array. Read `changes` to see what moved.
## Read the audit trail
`GET /v1/zero_touch_assessment/{assessment_id}/audit`
Every review action on a run, in the order taken.
`approved`, `escalated`, `corrected`, `rescored`, `revised`, `restored`, `rerun_requested`, `note`, or `archived`.
The reviewer's own words, stored verbatim, for `corrected` entries.
One entry per field the action changed, each with `field`, `before` and `after`. Empty for approvals, notes, and corrections that resolved to nothing.
The Zero Touch Score either side of the action.
The trail is append-only. There is no update or delete endpoint, by design. A Zero Touch Score can be pushed onto a vendor's risk score, so the record of who changed the inputs behind it must be one nobody can rewrite.
## Read and set scoring configuration
`GET /v1/zero_touch_assessment/config`
Returns whether the module can run (`is_ready`), the control sets in scope, and the current scoring configuration.
`POST /v1/zero_touch_assessment/config`
Sets what counts toward the score and where the score goes.
Whether the Financial Health Score is a component.
Whether the outside-in security rating is a component.
Relative weight of the control evaluation. Weights are relative, not percentages. They renormalise over whichever components resolve.
Relative weight of the financial health component.
Relative weight of the security component.
Whether corporate-registration standing is a component.
Relative weight of the registration component.
Whether the leadership dossier is a component.
Relative weight of the people component.
The `people` component deducts for adverse-media findings **only when screening ran**. When it did not, the component scores leadership visibility alone and says so in its `qualifier`. Do not read its score as evidence of a clean record. See [People Intelligence](/products/people-intelligence).
Where a completed run writes its score: `none`, `vendor_inherent`, `vendor_residual`, `service_inherent`, or `service_residual`.
Only the axis you choose is written, so a Zero Touch run can never overwrite an inherent score your team set deliberately from an intake questionnaire. A vendor-scoped run configured for a service target writes nothing and reports why in `result.push_skipped_reason`.
Whether a completed run writes its **risk tier** onto vendor inherent risk. Off by default.
Whether a finished run is checked a second time against the vendor's own pages, with the supported changes applied as a new version of the result. On by default.
The tier is a triage read from public evidence, so an organization that has not asked for it never finds a vendor's inherent risk moved by one. Even when enabled, the push stands down if `score_target` is already `vendor_inherent`, because two writers on one field would let run order decide the vendor's risk, and reports why in `result.risk_tier_push_skipped_reason`.
## Listing runs
There is no separate list endpoint, deliberately. A Zero Touch run is an assessment. Use the assessment query endpoint, `POST /v1/assessment/query`, with a rule on the `is_zero_touch` filter path (see the [field catalog](/fields/catalog#assessments)):
* `is_zero_touch: true` returns triage runs only
* `is_zero_touch: false` returns full assessments only
* omitted returns both
A second read path would be free to drift from the first.
## Via MCP
The same data is available to agents through the Coverbase MCP server:
```
query_assessments(kind="zero_touch", assessment_id="cbqsrw_...")
query_assessments(kind="zero_touch_leaderboard", limit=25)
query_assessments(kind="zero_touch_audit", assessment_id="cbqsrw_...")
```
All three are read-only and org-scoped to the authenticated user. See the [MCP overview](/mcp/overview).
# Changelog
Source: https://docs.coverbase.com/changelog
Notable changes to the Coverbase public API documentation.
## 2026-10-14: Document uploads and risk scores on the Intake API
### New features
* **Attach files to an intake created by API.** Upload each file with [`POST /v1/intake/api/documents`](/api-reference/intake#upload-a-document), then name the returned IDs in `document_ids` when you [create the intake session](/api-reference/intake#create-an-intake-session). Coverbase reads the files when it answers the questionnaire, the same way it reads files uploaded on the intake portal, and moves them onto the vendor record when the intake is submitted.
### Updates
* **Documents on intake sessions.** [`GET /v1/intake/api/sessions/{session_id}`](/api-reference/intake#get-an-intake-session) and its `external_id` variant now return `documents`, with each file's `vendor_document_id` once the intake is submitted.
* **Inherent risk score on intake sessions.** [`GET /v1/intake/api/sessions/{session_id}`](/api-reference/intake#inherent-risk-score) and its `external_id` variant now return `raw_irq_score` and `inherent_risk_level` once the session is `complete`. The score is calculated the same way approval scores the vendor, and the level comes from your organization's default risk scale.
***
## 2026-10-14: Assessment Settings in sections
### Updates
* **Assessment Settings is organized into sections.** A section list down the left of **Configuration > Assessment Settings** opens one part of the page at a time: **Plans**, **Workflow**, **Analysis**, **Reports**, **Document Collection**, **Reassessments** (with **Monitoring** beneath it when monitoring records are on) and **SLA Targets**. Every setting is unchanged and keeps working as before. Word report templates and the report file name are under **Reports**; reviewer, creation and approval settings are under **Workflow**.
***
## 2026-10-14: Confirm inherent risk before a reassessment
### New features
* **Inherent risk check before a reassessment.** An assessment plan can send your IRQ to the vendor's relationship owners before each reassessment starts, prefilled with last cycle's approved answers. Nothing goes to the vendor until the check is confirmed or skipped, and the plan then picks questionnaires and control sets from the refreshed inherent risk. Unchanged answers start the assessment on their own. See [Confirm inherent risk before a reassessment](/user-guides/reassessment-irq-review).
### Updates
* **Assessment plans API.** Assessment plans accept and return `irq_review_questionnaire_id` and `irq_review_due_days`, and `POST /v1/assessment/from_plan` accepts `confirm_inherent_risk_first`.
***
## 2026-10-08: Vendor ID on intake sessions
### Updates
* **Vendor ID on intake sessions.** [`GET /v1/intake/api/sessions/{session_id}`](/api-reference/intake#get-an-intake-session) and its `external_id` variant now return `vendor_id`, the vendor the request created or linked. Match it to the `vendor_id` on an assessment to find the assessment an intake leads to. See [Find the assessment an intake leads to](/api-reference/intake#find-the-assessment-an-intake-leads-to).
***
## 2026-10-08: The third-party lifecycle
Your Coverbase representative turns on the third-party lifecycle features for your organization.
### New features
* **Intake Agent.** Zero-form intake: requesters ask for a new vendor in Slack, Microsoft Teams, email or their AI assistant, and the agent asks only for what is missing before opening the intake. See [Intake Agent](/products/intake-agent).
* **Front Door.** Triage each intake request before due diligence: identifier matching on tax ID, D-U-N-S and LEI, engagement reuse by risk domain inside a reuse window, a disposition signed off by the TPRM Office and Supply Chain, IRQ scoping rules that send the questionnaire once, a Do Not Use list that needs an override rationale to approve, **Approve triage** from the request header, and **Decline**, which sends the disposition back to the TPRM Office with your reason. See [Front Door](/products/front-door).
* **Risk methodology.** One page for domain weights, three aggregation methods including a domain floor, a reviewer matrix by requesting group, business unit, tier and domain, SLA escalation rules, versioned inherent risk questionnaires with a changelog, review cadence and side-by-side version compare, an escalation log, inherent and residual what-if scoring, and score overrides that need a rationale and can expire, with a countdown. See [Risk methodology](/products/risk-methodology).
* **Due diligence.** Assessment methods with remote and onsite review sessions, question delegation in the supplier portal, answers carried forward from the last submission, reviewer edits the supplier approves, service-level questionnaires for vendors whose due diligence is current, and findings raised on a question. See [Due diligence](/products/due-diligence).
* **Claim check.** Each questionnaire answer tested against the vendor's SOC reports, certifications, trust center documents, outside-in scan, licensed ratings and contract terms, with cited passages, then findings raised or the vendor asked in bulk. See [Claim check](/products/claim-check).
* **Issue acceptance chain.** Route accepting a finding's risk through the owner, a recommending Risk Group, the deciding TPRM Office and an extended approver, enforced on every way a finding can reach risk accepted, with decisions in bulk. See [The issue acceptance chain](/user-guides/issue-acceptance-chain).
* **Engagement record and Risk Summary.** A shared tracker from request to exit, including an **Exit** stage after **Active**, with an expected decision date, Risk Group status, linked and reused diligence, and a Risk Summary with a recommendation, conditions, a PDF, the Transaction Owner's decision and opt-in email open tracking. See [Engagement record](/products/engagement-record).
* **Clause packs and non-standard contracts.** The clauses an engagement's risk results and open issues require, whether the draft carries each, obligations monitored after signature, and a portfolio report of non-standard clauses. See [Clause packs](/products/clause-pack).
* **Monitoring plans and scorecards.** A plan per engagement from a tier by activity cadence matrix, signal re-timing with undo under an agent policy, an IRQ refresh with an answer diff, a comparison of any submission with the earlier one, owner attestation, performance scorecards, contract obligations, and the Monitoring workbench for rescheduling and sending scorecards in bulk. See [Monitoring plans](/products/monitoring-plans).
* **Offboarding and continuity.** The executed contract handoff, continuity plans for critical engagements, and offboarding with an exit plan that closes only on approved evidence, including a vendor-signed data destruction certificate, with evidence and approvals in bulk. See [Offboarding and continuity](/products/offboarding-and-continuity).
* **Integration Hub.** Coupa, SAP Ariba, Ironclad, Icertis, Archer, ServiceNow IRM, an ERM risk register and Microsoft Teams, with field mappings, a sync log, a steward queue with bulk linking, signed inbound webhooks, and approvals from Teams cards through your own bot. A sign-off made in Coverbase updates the Teams card too. See [Integration Hub](/products/integration-hub).
* **Certificate Vault and prequalification.** Every certificate in one place, renewals requested in bulk, ISNetworld, Avetta and EcoVadis networks, prequalification rule sets that can block purchase orders, and Bitsight, SecurityScorecard, RapidRatings and Moody's ratings in Radar. See [Certificate Vault](/products/certificate-vault).
* **Warehouse data share.** Push 18 program tables to Snowflake, Amazon S3 or BigQuery hourly or daily, with a guided S3 trust policy step and plain-language errors. See [Warehouse data share](/products/warehouse-data-share).
* **Program Insights.** Program Overview under Dashboards: five KPIs, residual risk by business unit and risk domain, the pre-contract pipeline, three levels, six slicers with geography regions such as EU and North America, an ordering for business units, drill-downs that filter the matching lists exactly, Excel and CSV export, the board pack and the Distribution card. See [Program Insights](/products/program-insights).
* **Integration platforms.** Starting points for Workato (a custom connector), MuleSoft (a Mule 4 template) and Boomi (a process recipe) on the public API. See [Integration platforms](/integrations/guides/integration-platforms).
* **Agent Ledger and AI governance.** A record of every agent action and the human decision on it, decided one at a time or in bulk, agent policies enforced where agents act, a filtered audit export, redaction of personal data before model calls, and learning from your own reviewers. See [Agent Ledger](/products/agent-ledger).
* **Public API.** OAuth 2.0 client credentials (`POST /v1/oauth/token`), [contract records](/api-reference/contract-records) and [engagement records](/api-reference/engagement-records). See the [OAuth API](/api-reference/oauth).
### Documentation
* Fourteen product pages in a new **Third-party lifecycle** group, fifteen user guides, twenty integration guides, three API reference pages, and a new [Integration credentials and signing](/security/integration-credentials) security page. [AI governance](/security/ai-governance) gains redaction, the Agent Ledger and learning.
* The [integration directory](/integrations/directory) now links every name with a connector or a documented feature behind it, and says plainly that an unlinked name has no built-in connector.
## 2026-10-07: A calmer Financial health page
The Financial tab now answers first and puts the evidence one click away. Nothing was removed from the page.
### Changes
* **Your rating leads.** When your organization has a credit policy, the page opens with the vendor's financial stability rating. The Financial Health Score, the peer benchmark and the runway sit in one row under it.
* **The score's own scale.** The scale under the score uses the score's risk bands, from **Very high** to **Very low**, so the band named beside the number matches where the marker sits.
* **Evidence in rows.** Everything behind the verdict sits in collapsed rows, each with a one-line summary. **On this page** opens the row you pick.
* **One Export menu.** The PDF report, the Excel workbook and the analytics workbook are under **Export**.
### Documentation
* The [financial health guide](/user-guides/financial-health-score#reading-the-page) explains the new layout and gains sections on [your credit policy rating](/user-guides/financial-health-score#your-credit-policy-rating) and the [industry comparison](/user-guides/financial-health-score#industry-comparison).
***
## 2026-10-01: Security ratings compared with industry peers
The Security tab now compares a vendor with the companies that sell what it sells, not only with your own portfolio.
### New features
* **Industry Comparison.** Coverbase chooses three to seven peers for the product your organization buys from the vendor, scans each one with the same outside-in scan, and shows the vendor's factor scores against the industry average as a radar chart, then every company's rating with its band. See [Compared with industry peers](/user-guides/security-intelligence#compared-with-industry-peers).
* **Industry peers beside the rating.** The top right of the rating card gives the industry average, the vendor's rank, and every rated company on a strip of the rating scale.
* **Shared peer research.** Peers and their ratings are stored once and shared by every organization that buys the same product from the same company. Peers are chosen again every 90 days, a peer's rating is refreshed once it is more than 30 days old, and **Choose peers again** re-chooses them sooner.
* **In the PDF export.** The Security PDF carries the radar chart with its figures and a tile for every company.
### Documentation
* The [security intelligence guide](/user-guides/security-intelligence#compared-with-industry-peers) gains a section on reading the comparison, how peers are chosen and how they stay current, with three troubleshooting rows. The [product page](/products/security-intelligence) explains where peers come from.
***
## 2026-09-27: One base URL
Every example, and the base URL table in [API conventions](/conventions#base-urls), now uses `https://api.coverbase.app`, the only host that serves the public API. The second host these pages listed never served it and has been removed.
## 2026-09-24: Security Intelligence tells you what to do next
The Security tab now opens with what to do and what changed, ranks a vendor among your other rated vendors, and carries both into reports and MCP.
### New features
* **Next steps.** Every security profile carries a ranked list of actions, most urgent first, each resting on a named observation: an actively exploited CVE, a database or remote-desktop port open to the internet, a failing certificate, DMARC that does not enforce, a mail-capable lookalike domain, staff credentials in a breach within the last year. **Ask the vendor** copies a question that quotes the observed value, and **Go to** jumps to the evidence. The rules run when the profile is read, so every vendor scanned before today has a list now. See the [security intelligence guide](/user-guides/security-intelligence#next-steps).
* **Since last scan.** Each refresh records what it found that the previous one did not: the score and factor movement, findings that appeared or were resolved, vulnerabilities that appeared or are no longer observed, assets that arrived or left. Each count opens to the names behind it, and the factor rows carry the same movement as a badge. A finding counts as resolved only when its factor was measured in both scans. See [since last scan](/user-guides/security-intelligence#since-last-scan).
* **Standing among your vendors.** With at least five rated vendors, the rating shows where this one sits among them, such as **Top 30%**, computed from the ratings as they stand when you open the page. See [standing among your vendors](/user-guides/security-intelligence#standing-among-your-vendors).
* **Jump links and a security timeline.** A row under the rating links to each section this scan produced, and the drawer at the bottom of the page lists every dated fact on the profile as one chronology: ratings, when each finding was first seen, breaches, assets arriving and leaving, and disclosed incidents.
* **In reports and exports.** The PDF export opens with the next steps and the change log. Report templates gain `{{intelligence::security next steps}}` and `{{intelligence::security change since last scan}}`, and the security posture section an agent or MCP client reads now carries both blocks.
### Documentation
* The [security intelligence guide](/user-guides/security-intelligence) gains sections on next steps, since last scan, standing among your vendors and the security timeline, with four troubleshooting rows. The [product page](/products/security-intelligence) explains how the rules are chosen and evaluated, and the [template placeholders](/reporting/template-placeholders#security-posture) reference lists the two new placeholders.
***
## 2026-09-10: Ask your documents a question
Ask a question in chat and Coverbase reads the vendor's documents to answer it, returning the passage the answer rests on.
### New features
* **Document evidence pulls.** Ask something like "does Acme's SOC 2 cover encryption at rest?" through a connected assistant. Coverbase filters the vendor's documents on metadata, lets a model pick the one or two most likely to hold the answer, reads them, and returns a direct answer with a verbatim quote, its page number, a confidence, and a cropped image of the page with the passage highlighted. See [Asking your documents a question](/user-guides/document-evidence-pull).
* **Links that open the document highlighted.** Every answer carries a link that opens the document preview on the right page with the passage marked. The highlight travels as the quote itself rather than as page coordinates, so it still resolves after a re-render that would move a stored bounding box.
* **Repeat questions reuse what was already quoted.** Passages earlier work cited from the same documents are offered to the selection step, so a question already answered can come back without opening anything. A passage whose underlying insight has since been re-extracted is never reused.
* **Scanned documents are readable.** A pull reads the searchable rendition produced at ingestion, so an OCR'd scan answers and highlights like a native PDF. Excel workbooks are read as workbooks and cite a sheet name instead of a page.
* **`pull_document_evidence` prompt.** A scripted version of the whole flow, in the prompt menu of any connected client. See [Canned prompts](/mcp/prompts).
* **Sharper document filters over MCP.** Listing a vendor's documents now narrows on free text, document type, status, service, and upload date range.
### Documentation
* New guide: [Asking your documents a question](/user-guides/document-evidence-pull), covering what comes back, how documents are chosen, reading an answer critically, and the limits.
* The [tool reference](/mcp/tool-reference) and [example prompts](/mcp/example-prompts) gain the evidence routes.
***
## 2026-09-09: Reputational risk on a Zero Touch run
A Zero Touch run now reports what it found against the vendor's name as its own section, in the app and in both exports.
### New features
* **Reputational risk section.** Adverse media on the vendor's leadership, open watchlist matches where your organization screens, and the run's own reputation controls now arrive as one section rather than three places to go looking. Findings are filed under five dimensions: media and customer sentiment, litigation exposure, regulatory and enforcement, executive conduct and stability, and sanctions and association. See the [Zero Touch guide](/user-guides/zero-touch-assessments#reading-the-reputational-section).
* **Not screened is never reported as clear.** Each dimension reports its own standing, and a dimension nothing searched reads **Not screened** rather than **Clear**. The section names every unscreened dimension, so a short findings list is not mistaken for a clean vendor.
* **Material findings first.** A matter the subject was cleared of, or one a reviewer has dispositioned, is still listed because it is part of the record of what the run read. It is not counted as material and it does not deduct from the score.
* **Second in both exports.** The section prints straight after the vendor identity in the PDF, with the overall standing on the first page. The spreadsheet carries the read on the summary sheet under the score and a **Reputational risk** tab beside it, one row per finding with its publisher, date and link. The portfolio export gains reputational standing and material finding count columns.
### API
* `GET /v1/zero_touch_assessment/{id}` returns `result.reputation`, carrying the overall standing, the five `dimensions` and the `findings` behind them. It is `null` on a run scored before this shipped, which means the run never assembled one rather than that the vendor is clear. See the [API reference](/api-reference/zero-touch-assessments#read-a-run).
### Documentation
* The [Zero Touch guide](/user-guides/zero-touch-assessments) gains a section on reading the reputational read, an updated export walkthrough, and a troubleshooting row on the difference between **Not screened** and **Clear**.
***
## 2026-09-05: Review a vendor's attributed estate
Security Intelligence now shows every domain and address it attributes to a vendor as a list you can correct, and every finding carries the step that resolves it.
### New features
* **Attributed estate.** The Security tab lists every asset the scan attributes to the vendor, with when each was first and last seen. Filter to what still needs a decision, and **Confirm** or **Dispute** each one from its row. A disputed asset leaves the next scan and the rating; withdrawing the dispute puts it back. See the [security intelligence guide](/user-guides/security-intelligence#attributed-estate).
* **Add the assets the scan cannot find.** Discovery reads certificate transparency, so a host with no public certificate never appears. **Add asset** puts them in the estate, one per line or comma-separated, and the next scan probes and scores them like any other. One submission costs one rescan however many hosts it carries, and assets you add survive a scan that cannot see them.
* **Remediation on every finding.** Opening a finding shows what was observed, whether it cost the rating points and how many, how long it has been open, and the step that fixes it. Forwarding one to a provider now hands them the change to make rather than the problem to research.
* **Generate findings in bulk.** **Generate findings** raises a tracked finding for every scored issue at once, ticked by default and ordered by severity, for the sweep that turns up the same problem on a dozen hosts.
* **Transport checks per host.** TLS is measured on each attributed host rather than only the vendor's main domain, so one neglected server does not hide behind a well-configured front door.
### Fixes
* DNSSEC, TLS reporting and email authentication no longer read as failures for domains that have not adopted them. Non-adoption is now recorded as an observation rather than scored like a misconfiguration, and DNSSEC is read from the signed zone rather than from the resolver's answer.
### Documentation
* The [security intelligence guide](/user-guides/security-intelligence) gains sections on opening a finding, raising findings from a scan, and reviewing the attributed estate, with new screenshots and three troubleshooting rows.
***
## 2026-09-01: Radar signals
Radar now works as one signal per event instead of the old per-detector alerts feed, with titles and summaries written for your organization.
### New features
* **Signals.** Every event your organization is exposed to appears once on the new **Signals** tab, as a signal carrying a status (Tracked, Open, In alert, Triaged, Dismissed), the highest severity any detector assigned, and the vendors and detectors involved. Each detector's verdict stays visible on the signal's **Detectors** tab. See the Supplier Radar [key concepts](/products/supplier-radar#key-concepts).
* **Tracked exposure.** A signal appears as soon as a vendor you depend on is linked to an event, before any detector fires, so fourth-party exposure is visible before anything has fired.
* **Generated titles and summaries.** Each signal's title and summary are written for your portfolio and regenerated when the detectors that fired change. Edit them by hand, click **Regenerate summary**, or set **Custom AI instructions** that apply to every summary in your organization.
* **Configuration moved.** Detectors and sources now live under **Configuration → Radar**, reached from the **Configurations** button on the Radar page.
### Documentation
* [Step 8 of the analyst guide](/user-guides/analyst-reviewer#step-8-work-radar-signals) and [step 9 of the admin guide](/user-guides/admin-setup#step-9-configure-radar-continuous-monitoring) are rewritten around signals, with new screenshots. The [field catalog](/fields/catalog#radar-signals) now mirrors the Signals tab, and the [Radar API](/api-reference/radar) reference explains how events and alerts map to signals.
***
## 2026-08-27: Internal Controls Library for Inspect
The control set library is now two libraries. The existing frameworks stay where they were, under a renamed **Vendor Controls Library**, and a new **Internal Controls Library** holds control sets Inspect evaluates against your own applications.
### New features
* **Internal Controls Library.** A new library of **21 templates spanning 362 controls**, written for [Coverbase Inspect](/products/agentic-inspect) to evaluate against the applications you run rather than against a vendor. Covers identity and privileged access, application scope and feature drift, integrations and OAuth, data handling, PII, PHI/HIPAA, GDPR, AI features and AI agents, operational resilience, SLA conformance, audit logging, licensing, and the CRM, HRIS and financial-services application classes. See the [Control Set library](/control-library#internal-controls-library).
* **Vendor Controls Library.** The existing 47 framework templates are unchanged and now open from the **Vendor Controls** tab. Together the two libraries hold **68 templates spanning 4,337 curated controls**.
* **Controls written for a browser agent.** Each internal control states an expectation carrying its own threshold, names the admin surface to read plus the alternate labels other vendors use for it, and defines what counts as incomplete. Incomplete is a real outcome rather than a failure, so an application that does not sell a capability is not marked down for lacking it.
***
## 2026-08-11: Web evidence credibility grading and evidence dates
Web evidence used in assessments is now graded for publisher accountability and filtered against a minimum you configure, and accepted citations record how old the evidence was when it was used.
### New features
* **Source credibility grading and filtering.** Every candidate web page retrieved while evaluating a control is graded **Unreliable**, **Reputable**, or **Authoritative**, and pages below the configured minimum are discarded before the evaluating model sees them. Grades are shown on evidence cards with the reason on hover, and exported in a **Source credibility** column on the Evidence sheet. See [Evidence quality and source credibility](/user-guides/evidence-quality).
* **Minimum credibility on evidence sources.** Web-search evidence sources carry a `minimum_credibility` field (`unreliable`, `reputable`, or `authoritative`, defaulting to `reputable`), settable on a control set or on an individual control. Control-level evidence sources replace the set's entirely, including this setting.
* **Evidence dates and age.** Accepted web citations record the publication or last-modified date the page declares, and the evidence's age at the moment it was cited. Evidence cards show **Published** / **Last updated**, **Age when assessed**, and an absolute **Accessed** date; the Excel export adds **Evidence Date** and **Evidence Age When Assessed (Days)** columns.
***
## 2026-07-20: AI control sets, expanded detector library, integration directory
New out-of-the-box AI-governance control sets, a larger Supplier Radar detector library with a dedicated AI segment, and a documented directory of external integrations.
### New features
* **AI-governance control sets.** The [Control Set library](/control-library#ai-governance) adds five built-in frameworks (**AIUC-1**, **ISO/IEC 42001:2023**, the **EU AI Act**, the **OWASP Top 10 for LLM Applications (2025)**, and **MITRE ATLAS**), bringing the library to 47 templates spanning 3,975 curated controls.
* **Detector library page.** A new [Detector library](/products/detector-library) reference documents all 75 Supplier Radar detector templates across 7 segments, including a new **AI & Model Risk** segment (prompt injection, model safety incidents, training-data/IP disputes, AI regulatory enforcement, and more).
* **Integration directory.** A new [Integration directory](/integrations/directory) lists the external systems Coverbase connects with by category, including a new **AI Governance & Safety** category, a **Compliance Automation & Trust Management** category, and additions such as Aravo across GRC, procurement, and cybersecurity.
***
## 2026-06-17: List vendors, discover questionnaires, filter supplier exports
New read endpoints for discovering IDs without leaving the API, plus a name filter on supplier exports.
### New features
* **List vendors.** `GET /v1/vendors` lists the org's vendors (newest first), with a case-insensitive `name` substring filter, an exact `external_id` lookup, and `limit`/`offset` pagination, so you can enumerate vendors or map your own identifier to a Coverbase vendor ID. See the [Vendors API reference](/api-reference/vendors#list-vendors).
* **List questionnaires.** `GET /v1/intake/api/questionnaires` returns the org's questionnaires (`id`, `name`, `type`), with an optional `type` filter. Use it to discover the `questionnaire_ids` that [`POST /v1/intake/api/sessions`](/api-reference/intake#create-an-intake-session) requires. See the [Intake API reference](/api-reference/intake#list-questionnaires).
### Updates
* **Supplier export filter.** [`GET /v1/export/{report_name}`](/export) now accepts a `supplier_name` query parameter that filters vendor-based reports (for example, the all-suppliers report) by name.
* **Import API troubleshooting.** Clarified the most common `404`/`422` causes in the [Import API reference](/import): the path is singular (`/v1/import/...`), the body must be wrapped under `data`, and a service-account key is required.
***
## 2026-06-08: Documents API
Upload vendor evidence documents over the REST API and through the MCP server, link them to vendors, services, and assessments, and download them.
### New features
* **Documents API.** `POST /v1/documents` uploads a file (`multipart/form-data`) and attaches it to a vendor, optionally linking it to services (`service_ids`) and assessments (`assessment_ids`) in the same call. List with filters (`GET /v1/documents?vendor_id=&service_id=&assessment_id=`), fetch metadata (`GET /v1/documents/{document_id}`), get a short-lived presigned download URL (`GET /v1/documents/{document_id}/download`), re-link or rename (`PATCH /v1/documents/{document_id}`), and archive (`DELETE /v1/documents/{document_id}`). Smart limits apply: 100 MiB per file, an allowed file-type list, and 1-200 page sizes. See the [Documents API reference](/api-reference/documents).
* **MCP document tools.** The MCP server adds `mutate(document, create|update|archive)` (upload from a URL, re-link, archive) and `query_vendors(document_download)` (presigned download URL), alongside the existing `query_vendors(documents|document_summary)` reads.
### Updates
* **Assessment supporting documents.** `supporting_document_ids` on [`POST /v1/assessments`](/api-reference/assessments) now links documents uploaded via the Documents API.
***
## 2026-06-04: Vendor fact sheet API
Read and regenerate a vendor's AI-generated fact sheet (company intelligence) over the REST API.
### New features
* **Vendor fact sheet API.** `GET /v1/vendors/{vendor_id}/fact-sheet` returns the vendor's fact sheet (company profile, products, public perception, financials, people, compliance/legal, and security posture) along with a generation `status`. `POST /v1/vendors/{vendor_id}/fact-sheet/refresh` queues a (re)generation and returns `202 Accepted`; poll the read endpoint until `status` is `"completed"`. See the [Vendors API reference](/api-reference/vendors#the-vendor-fact-sheet).
***
## 2026-06-04: List and resolve users by email
The Users API can now look up a user by email and returns the existing user on a duplicate create, so external systems (for example, ServiceNow) can build an email → user ID mapping for relationship-owner / watcher / risk-analyst assignments.
### New features
* **List users / look up by email.** `GET /v1/users` lists the org's users (paginated via `limit`/`offset`, optional `include_archived`), or resolves a single user with `?email=` (case-insensitive exact match; returns the user even if archived). See the [Users API reference](/api-reference/users#list-users-and-look-up-by-email).
### Updates
* **`POST /v1/users` is now create-or-get.** When a user with the supplied email already exists in the org, the endpoint returns `200 OK` with that user (so you can resolve its `cbuser_...` ID) instead of `409 user_exists`. A `409` is now only returned when the email belongs to a user in a **different** org (emails are globally unique).
* **Assigning people by email.** The [vendor & service](/api-reference/vendors#assigning-people-analysts-owners-watchers) `relationship_owner_ids`, `watcher_ids`, and `risk_analyst_ids` fields still take user IDs. The Users API is the supported path to resolve those IDs from emails.
***
## 2026-06-02: Bill of Materials
Upload, version, and search machine-readable bills of materials (SBOM, AIBOM, HBOM, SaaSBOM) for vendors and services, over the REST API and through the MCP server.
### New features
* **Bill of Materials API.** Upload a BOM as a document linked to a vendor or its services (`POST /v1/bill_of_materials`), and Coverbase parses CycloneDX and SPDX JSON in the background into a searchable list of components. Read the current applied BOM for a vendor or service (`GET /v1/bill_of_materials/latest`), page the full upload history (`GET /v1/bill_of_materials`), retrieve one BOM with its components, search components within a BOM or across all of a vendor's BOMs, and archive a BOM. Only the latest non-archived BOM is "applied"; older ones stay viewable as history. See the [Bill of Materials API reference](/api-reference/bill-of-materials).
### Updates
* **MCP & AI assistants.** The `query_vendors` tool gained two read-only kinds: `bill_of_materials` (the latest applied BOM and its components) and `bill_of_materials_history` (every uploaded BOM for a vendor, newest first). See the [example prompts](/mcp/example-prompts#bill-of-materials).
* **Conventions.** The ID-prefix table now lists `cbbom_` (bill of materials) and `cbbomc_` (component). See [IDs](/conventions#ids).
The feature is gated by the org-level `bill-of-materials` entitlement. While it is off, the `/v1/bill_of_materials` routes return `404`. Ask your administrator to enable it.
***
## 2026-05-29: Radar & reassessments come to the API
Programmatic access to continuous monitoring: create radar events, triage alerts, and drive reassessments end-to-end, plus webhooks for all three.
### New features
* **Radar API.** Create radar events (`POST /v1/radar/events`), list and retrieve events, and list, retrieve, dismiss, and undismiss radar alerts. Dismissing with `suppress_similar` teaches the detector to suppress similar alerts going forward. See the [Radar API reference](/api-reference/radar).
* **Reassessments API.** Create a reassessment from a radar event with its vendors, curate the vendor set (add vendors, opt vendors in/out), set the assessment plan, then `confirm`, `dismiss`, or `run` it. Running creates one assessment per included vendor from the linked plan, and never opens a case. See the [Reassessments API reference](/api-reference/reassessments).
* **Radar & reassessment webhooks.** Subscribe to `RadarEvent.*`, `RadarDetectorResult.*` (radar alerts), and `Reassessment.*` events. `*.Updated` events carry per-field `field_diffs`; soft-archives surface as `*.Deleted`. See the [event catalog](/integrations/webhooks#event-catalog).
### Updates
* **MCP & AI assistants.** The Coverbase MCP server can now read reassessments (`query_radar` kind `reassessments`) and create radar events, dismiss alerts, and create/update reassessments (`mutate`). The in-product Interrogate assistant can propose the same radar/reassessment actions on a vendor.
***
## 2026-05-22: This week at Coverbase
A big week for the public API: self-serve key management, deeper workflow visibility, automatic webhook delivery, and tighter network controls.
### New features
* **Self-serve API key management.** Admins can now list, create, rotate, and revoke their org's `ak_*` keys without filing a support ticket. Rotation is atomic, so you'll never have two valid keys live at the same time. See the [API Keys reference](/api-reference/api-keys).
* **Scoped admin API keys.** Admins can mint long-lived `ak_*` keys carrying the `keys:manage` and/or `audit:read` scopes, so key management and audit-log reads can run headlessly, without a short-lived dashboard JWT. The admin-JWT path is unchanged and still works. Granting scopes stays an admin-only action (a scoped key cannot grant scopes to itself or any other key), and a key missing the required scope gets `403 insufficient_scope`. See [API key scopes](/conventions#api-key-scopes).
* **List workflow runs.** Page through workflow run history with filters for workflow name, status, and time range. No need to know a run ID up front. See [List workflow runs](/api-reference/workflows#list-workflow-runs).
* **Archive an assessment via API.** `DELETE /v1/assessments/{id}` mirrors the in-product Archive action: it soft-deletes the assessment along with its evals and findings, closes the portal if open, and cancels any in-flight workflow runs. See [Cancel (archive) an assessment](/api-reference/assessments#cancel-archive-an-assessment).
* **Public API audit log.** Every authenticated `/v1/*` call is now recorded and visible to admins under **Settings → Audit log** (Integrations group), or via `GET /v1/system_audit_log`. Request and response bodies are never persisted. See [Public API audit log](/conventions#public-api-audit-log).
* **Org-level API IP allowlist.** Restrict all public API traffic to a set of CIDRs. Requests from outside the allowlist are rejected with `403 ip_not_allowed`. See [API IP allowlist](/conventions#api-ip-allowlist).
* **Workflow `send_webhook` action.** Workflow automations can now deliver their triggering event to subscribed webhooks, with optional event-type override and an optional subset of recipient webhooks. See [Workflow engine → Actions](/integrations/workflow-engine#actions).
### Updates
* **Per-stage workflow outcomes.** `GET /v1/workflows/runs/{id}` now returns the outcome of every executed step: status (`success`, `failed`, `skipped`), an optional message, the artifacts consumed and produced, and a per-step timestamp. Existing fields are unchanged. `completed_at` also now populates on canceled runs.
* **Automatic webhook delivery is live.** Subscribed webhooks now receive a fan-out delivery whenever a matching domain event occurs. Previously only the manual test endpoint dispatched a delivery. All webhooks for a single source event share an `event_id` so receivers can dedupe. See [Webhooks](/integrations/webhooks).
* **Webhook delivery history.** Inspect every delivery attempt (event fan-out, manual test, or workflow-triggered) via the new `GET /v1/webhooks/{id}/deliveries` endpoint, and review aggregate stats (`last_delivery_status`, `delivery_success_rate`, `delivery_count`) on the webhook itself. See [Webhook delivery history](/integrations/webhook-deliveries).
### Breaking changes
* **Webhook event types are now strictly validated.** Creating or updating a webhook with an event type outside the [event catalog](/integrations/webhooks#event-catalog) now returns `422 invalid_event_types`. Casing matters: use `Vendor.Created`, not `vendor.created`. Review your registered subscriptions before your next deploy.
* **Webhook URLs are SSRF-restricted.** Webhook `url` must be a public HTTPS endpoint. Non-HTTPS URLs, URLs with credentials or non-standard ports, and URLs resolving to private, loopback, link-local, or metadata addresses are rejected with `400 invalid_url`. The same check runs at delivery time (DNS-rebinding safe).
### Fixes
* **API keys revoke is idempotent.** Re-revoking an already-revoked key returns success without writing a duplicate audit row. Audit entries are only written on actual state transitions.
***
## 2026-05-21: Self-serve API keys, workflow run listing, assessment archive, audit log
Additive features answering common customer questions on day-2 operations of the public API.
### Additive
* **Self-serve `ak_*` API key management.** New [API Keys API](/api-reference/api-keys) lets an org admin list, create, rotate, and revoke their organization's public-API keys without contacting Coverbase support. Rotation is atomic: a new key is minted, then the old one is revoked; if the revoke fails the new key is rolled back so there's never a window with two simultaneously-valid keys. At launch these endpoints were JWT-only (`ak_*` keys could not manage other keys); they now also accept an `ak_*` key carrying the `keys:manage` scope. See the **scoped admin API keys** entry above.
* **`GET /v1/workflows/runs`: list workflow runs.** Page through workflow run history without already knowing the run ID. Filterable by `workflow_name`, `status` (repeatable), and a created-at time range. Returns a `step_count` per run for at-a-glance progress. See [Workflows API → List workflow runs](/api-reference/workflows#list-workflow-runs).
* **Per-stage workflow outcomes.** `GET /v1/workflows/runs/{id}` now surfaces the action outcome of every executed step: `status` (`success` / `failed` / `skipped`), an optional `message` (carries the failure reason on failure), the consumed and produced `artifacts` (with `role` of `trigger` or `result`), and the step's `created_at`. The previous response (component id, name, action\_type, updated\_at) is unchanged so this is additive. `completed_at` now also populates on `canceled`.
* **`DELETE /v1/assessments/{id}`: cancel / archive an assessment.** Mirrors the in-product Archive action: soft-deletes the assessment plus its evals and findings, closes the portal if open, and best-effort cancels any in-flight workflow runs targeting the assessment. Idempotent at the row level. See [Assessments API → Cancel (archive) an assessment](/api-reference/assessments#cancel-archive-an-assessment).
* **Public-API audit log.** Every authenticated `/v1/*` request now writes a `CbActivity` row (`type=external_api_call`, `target_type=external_api_request`) with the method, path, route template, status code, duration, query parameter names, `ak_*` key id+name, client IP, and a request correlation ID. Visible to admins in **Settings → Audit log** under the *Integrations* group, and via `GET /v1/system_audit_log`. Request and response bodies are never persisted. See [API conventions → Public API audit log](/conventions#public-api-audit-log).
## 2026-05-16: Webhook event-type validation, SSRF restrictions, delivery history, and API IP allowlist
Reconciled against the `claude/webhook-ui-workflow` source branch. Two breaking changes and two additive features.
### Breaking
* **Webhook `events` is now strictly validated.** `POST /v1/webhooks` and `PATCH /v1/webhooks/{id}` reject any event type outside the supported [event catalog](/integrations/webhooks#event-catalog) with `422 invalid_event_types`. Previously the field was a free-form list of strings. Integrations that registered non-canonical values (for example, lowercase `vendor.created`) must switch to the exact catalog casing (for example, `Vendor.Created`) or their create/update calls will now fail.
* **Webhook URLs are SSRF-restricted.** A webhook `url` must be a public HTTPS endpoint. URLs that are non-HTTPS, carry credentials, use a non-standard port, or resolve to a private / loopback / link-local / metadata address (for example, `169.254.169.254`) are rejected at create/update with `400 invalid_url`. The same check is re-applied with DNS resolution at delivery time (DNS-rebinding safe); a delivery blocked this way is recorded with status `error`.
### Additive
* **Automatic event delivery is live.** Subscribed webhooks now receive a fan-out delivery whenever a matching domain event occurs (previously only the manual test endpoint dispatched a delivery). All webhooks for one source event share a single `event_id` so receivers can dedupe the fan-out.
* **Webhook delivery history.** New `GET /v1/webhooks/{id}/deliveries` endpoint (paginated, newest first) and a new [Webhook delivery history](/integrations/webhook-deliveries) page. Every attempt (event fan-out, manual test, or workflow-triggered) is recorded. The webhook object now also returns `last_delivery_status`, `delivery_success_rate`, and `delivery_count`.
* **Org-level API IP allowlist.** An org can restrict all `/v1/*` public API requests to a set of CIDRs via `api_ip_allowlist` on the org object (`POST /v1/org/{id}`). Requests from outside the allowlist get `403 ip_not_allowed`; the control fails closed. See [API conventions → API IP allowlist](/conventions#api-ip-allowlist).
* **Workflow `send_webhook` action.** Workflow automations can deliver their triggering event to subscribed webhooks, with an optional event-type override and an optional `webhook_ids` subset. See [Workflow engine → Actions](/integrations/workflow-engine#actions).
## 2026-05-16: Reconciled against the deployed source branch
Corrected the reference against the deployed branch. Changes vs. the prior pass:
* **Vendor `primary_contact`.** Create, update, and read now document the `primary_contact` object (`email` required + validated, plus `name`/`title`/`phone_number`). On read it is derived from stored contact personnel / security contact email.
* **Vendor `services`.** The vendor object now includes a `services` array (nested [service objects](/api-reference/vendors#service-object)).
* **Service updates.** Added `PATCH /v1/vendors/{vendor_id}/services/{service_id}` (name / description / tag\_ids → `service_not_found` 404, `invalid_service` 400). Service create now accepts `tag_ids`; the service object includes a `tags` string array.
* **User `email` is validated.** `POST /v1/users` rejects a non-email `email` with `422`; `409 user_exists` is also returned on a create race / global uniqueness conflict.
* **Findings: exactly one target.** `POST /v1/findings` now requires *exactly one* of `vendor_id`/`assessment_id`: supplying neither **or both** fails with `422` ("Exactly one of vendor\_id or assessment\_id must be provided.").
## 2026-05-16: Remaining endpoints documented
Added reference coverage for endpoints that were previously undocumented:
* **Users API**: `POST /v1/users` (provision, idempotent), `GET /v1/users/{id}`, `PATCH /v1/users/{id}` (role change / deprovision via `is_archived`). Documented org role values, `409 user_exists`, and the `invited`/`active`/`inactive` membership states.
* **Vendor & service creation**: `POST /v1/vendors` (idempotent) and `POST /v1/vendors/{id}/services` (not idempotent). Added the vendor `tier` field and `external_id` create input.
* **Findings API**: `GET`/`POST /v1/findings`, `GET`/`PATCH /v1/findings/{id}`. Documented the vendor/assessment filter, `limit`/`offset` pagination, the `cbtask_` ID prefix, and the "one of vendor\_id/assessment\_id required" rule.
* **Obligations API**: `GET`/`POST /v1/obligations`, `GET`/`PATCH /v1/obligations/{id}`. Documented the `satisfied`/`not_satisfied` status enum, CUEC type, and pagination.
* **Workflows**: the get-run response now documents `steps[]`; added `409 workflow_disabled` and `502 workflow_dispatch_failed`; clarified that running a workflow genuinely dispatches the engine (`Workflow.RunRequested`).
* Added a pagination section to [API conventions](/conventions); expanded the ID-prefix table (`cbtask_`, `cboblg_`, `cbsvc_`, `cbvdoc_`) and the idempotency support matrix.
## 2026-05-16: Documentation reconciled with the API
The API reference was rebuilt to exactly match the implemented public API. Highlights:
* **Resource surface corrected.** Fixed schemas for the vendors, assessments, workflows, and webhooks endpoints. (The Users, vendor/service creation, Findings, and Obligations endpoints were documented in the following entry once the deployed surface was confirmed.)
* **Vendor schema fixed.** `status` is a label string (not an object); `tags` is a string array (not objects). Added `status_id`. Removed fields that the API does not return (`raw_irq_score`, `next_assessment_date`, `last_assessment_outcome`).
* **Assessment schema fixed.** Removed the non-existent `risk_type`, `doc_collection_mode`, and `products` request fields. `control_set_ids` is required. Status values corrected to the real enum. Idempotency replays return the original `201` body (no `409 idempotency_conflict`).
* **Workflow schema fixed.** Run status values are `started`/`completed`/`canceled`/`failed`. The get-run response returns only run metadata: no `checkpoints_reached` or `output`. Removed the non-existent `429 rate_limited` / `400 invalid_input` errors and the non-existent `POST /v1/workflows/runs` alternative.
* **Webhook signing documented from source.** Signature header is `Coverbase-Signature` (lowercase hex HMAC-SHA256 of the raw body, keyed by the registered secret). Deliveries also send `X-Coverbase-Event-Id` and `X-Coverbase-Event-Type`. Envelope is exactly `{event_id, event_type, occurred_at, data}`. Retries are bounded at 5 attempts with a 10s per-attempt timeout (no documented multi-hour backoff window).
* **Event catalog corrected** to the emission-backed `SupportedEventType` values with exact casing (for example, `Vendor.Created`, not `vendor.created`). Removed invented events (`evaluation.flagged`, `evidence.requested`, etc.).
* Added a shared [API conventions](/conventions) page (auth, IDs, timestamps, idempotency, error envelope).
### Open questions
* **Automatic event delivery.** ~~No code path fans domain events out to subscribed webhook endpoints.~~ **Resolved 2026-05-16:** automatic fan-out is now implemented. See the latest changelog entry above and the [Webhooks](/integrations/webhooks) guide.
* **`supporting_document_ids` ID prefix.** The assessment create field accepts document IDs; the precise prefix is intentionally left unspecified pending confirmation.
# Control Set library
Source: https://docs.coverbase.com/control-library
Every built-in control set template Coverbase ships across both libraries: the vendor frameworks they map to, the internal application controls Inspect evaluates, their coverage, and links to the official sources.
Coverbase ships a curated **Control Set library**: ready-to-use control set templates you fork into your organization, tailor, and apply. Templates are versioned and maintained by Coverbase, and administrators can promote additional private templates from an uploaded spreadsheet.
The library has **two halves**, reached from different tabs on the **Controls** page:
**75 templates · 5,362 controls.** Frameworks, regulations and questionnaires you assess a *third party* against: ISO 27001, SIG, HECVAT, NIST CSF, HIPAA, PCI DSS and the rest. Opens from the **Vendor Controls** tab.
**22 templates · 392 controls.** Controls [Coverbase Inspect](/products/agentic-inspect) evaluates against *your own* applications by signing in and reading the live admin console. Opens from the **Internal Controls** tab.
That is **97 templates** spanning **5,754 curated controls** in total. This page documents each one in more depth than the in-app picker: its full description, the risk types and domains it addresses, typical use cases, its control count, and, where the template is derived from a published framework, a link to the authoritative source.
Which library a template appears in follows from the kind of control set it creates, so a template is only ever listed in one of them. Forking either one produces an ordinary control set you own and can edit; nothing syncs back.
Control counts and wording are Coverbase's structured interpretation of each source framework, intended to accelerate assessment. They are not a substitute for the official standard. Always consult the linked primary source for authoritative, legally binding text.
# Vendor Controls Library
The 75 templates below assess a third party. Fork one, tailor it, then apply it to vendors, services, or assessments.
## Cybersecurity & vendor security
| Template | Controls | Focus | Official source |
| - | -: | - | - |
| Coverbase Publicly Verifiable Vendor Controls | 28 | Information Security, Third-Party Risk | [Coverbase Content Library](https://www.coverbase.com/content-library) |
| CSA CCM/CAIQ v4.0 | 261 | Information Security, Third-Party Risk | [CSA Cloud Controls Matrix / CAIQ](https://cloudsecurityalliance.org/research/cloud-controls-matrix) |
| HECVAT Full (v4) | 227 | Third-Party Risk, Information Security | [EDUCAUSE - HECVAT](https://www.educause.edu/hecvat) |
| HECVAT Lite (v4) | 56 | Third-Party Risk, Information Security | [EDUCAUSE - HECVAT](https://www.educause.edu/hecvat) |
| ISO/IEC 27001 (2022 Edition 3) | 93 | Information Security, Regulatory Compliance | [ISO/IEC 27001:2022](https://www.iso.org/standard/27001) |
| MITRE ATT\&CK Framework | 52 | Information Security, Operational Risk | [MITRE ATT\&CK](https://attack.mitre.org/) |
| NIST CSF 1.1 | 108 | Information Security, Operational Risk | [NIST Cybersecurity Framework 1.1](https://www.nist.gov/cyberframework/framework) |
| NIST CSF 2.0 | 106 | Information Security, Operational Risk | [NIST Cybersecurity Framework](https://www.nist.gov/cyberframework) |
| SIG Core (2025) | 755 | Information Security, Third-Party Risk | [Shared Assessments - SIG](https://sharedassessments.org/sig/) |
| SIG Lite (2025) | 126 | Third-Party Risk, Information Security | [Shared Assessments - SIG](https://sharedassessments.org/sig/) |
| VSA Full (2025) | 106 | Third-Party Risk, Information Security | [Vendor Security Alliance](https://www.vendorsecurityalliance.org/) |
Coverbase's curated set of publicly verifiable security controls based on observable evidence available without vendor cooperation.
**Official source:** [Coverbase Content Library](https://www.coverbase.com/content-library)
* **Risk types:** Information Security, Third-Party Risk
* **Risk domains:** Vendor Due Diligence, Risk Governance
* **Typical use cases:** Initial vendor screening; Lightweight due diligence; Passive vendor risk assessment; Pre-engagement risk triage
* **Coverage:** 28 controls across 5 sections
Cloud Security Alliance Consensus Assessments Initiative Questionnaire v4, designed to assess cloud service providers against CCM security controls.
**Official source:** [CSA Cloud Controls Matrix / CAIQ](https://cloudsecurityalliance.org/research/cloud-controls-matrix)
* **Risk types:** Information Security, Third-Party Risk
* **Risk domains:** Cloud Security, Data Protection, Identity & Access Management
* **Typical use cases:** Cloud provider due diligence; SaaS vendor security assessment; Cloud security maturity evaluation; CSA STAR certification readiness
* **Coverage:** 261 controls across 17 sections
Higher Education Community Vendor Assessment Tool (HECVAT) Full v4, the long-form questionnaire for assessing vendor security in higher education contexts.
**Official source:** [EDUCAUSE - HECVAT](https://www.educause.edu/hecvat)
* **Risk types:** Third-Party Risk, Information Security, Data Privacy
* **Risk domains:** Vendor Due Diligence, Data Protection
* **Typical use cases:** Higher education vendor assessments; University third-party risk management; EdTech platform security evaluation; FERPA-aligned vendor due diligence
* **Coverage:** 227 controls across 18 sections
Higher Education Community Vendor Assessment Tool (HECVAT) Lite v4, a condensed questionnaire for lower-risk vendors in higher education environments.
**Official source:** [EDUCAUSE - HECVAT](https://www.educause.edu/hecvat)
* **Risk types:** Third-Party Risk, Information Security
* **Risk domains:** Vendor Due Diligence, Data Protection
* **Typical use cases:** Lightweight higher education vendor review; Annual vendor reassessments; Low-risk EdTech evaluation; Tiered vendor risk program (education)
* **Coverage:** 56 controls across 11 sections
ISO/IEC 27001:2022 Edition 3, the international standard for information security management systems (ISMS), updated with new controls for cloud security, threat intelligence, and privacy.
**Official source:** [ISO/IEC 27001:2022](https://www.iso.org/standard/27001)
* **Risk types:** Information Security, Regulatory Compliance
* **Risk domains:** Risk Governance, Data Protection, Cloud Security
* **Typical use cases:** ISO 27001 certification readiness; ISMS implementation assessment; International security compliance; Supply chain security evaluation
* **Coverage:** 93 controls across 4 sections
MITRE ATT\&CK framework controls mapped to adversary tactics, techniques, and procedures (TTPs) for evaluating threat detection and response capabilities.
**Official source:** [MITRE ATT\&CK](https://attack.mitre.org/)
* **Risk types:** Information Security, Operational Risk
* **Risk domains:** Threat Intelligence, Incident Response, Network Security
* **Typical use cases:** Threat detection capability assessment; Red team readiness evaluation; SOC maturity measurement; Adversary simulation alignment
* **Coverage:** 52 controls across 19 sections
The original NIST Cybersecurity Framework covering five core functions: Identify, Protect, Detect, Respond, and Recover. Widely adopted as the foundational cybersecurity standard.
**Official source:** [NIST Cybersecurity Framework 1.1](https://www.nist.gov/cyberframework/framework)
* **Risk types:** Information Security, Operational Risk
* **Risk domains:** Risk Governance, Network Security, Incident Response
* **Typical use cases:** Cybersecurity program baseline; Legacy CSF alignment; Security maturity measurement; NIST CSF 1.1 compliance verification
* **Coverage:** 108 controls across 23 sections
NIST Cybersecurity Framework 2.0, updated in 2024 with a new Govern function, covering cybersecurity risk management for organizations of any size.
**Official source:** [NIST Cybersecurity Framework](https://www.nist.gov/cyberframework)
* **Risk types:** Information Security, Operational Risk
* **Risk domains:** Risk Governance, Network Security, Incident Response
* **Typical use cases:** Cybersecurity program governance; Board-level security reporting; Regulatory baseline alignment; Third-party risk governance
* **Coverage:** 106 controls across 22 sections
The Shared Assessments SIG Core questionnaire, an 800+ question vendor risk assessment covering 20 risk domains.
**Official source:** [Shared Assessments - SIG](https://sharedassessments.org/sig/)
* **Risk types:** Information Security, Third-Party Risk, Operational Risk
* **Risk domains:** Vendor Due Diligence, Cloud Security, Identity & Access Management
* **Typical use cases:** Full third-party vendor due diligence; Enterprise vendor risk assessments; Outsourced service provider evaluations; Regulatory-aligned vendor management
* **Coverage:** 755 controls across 33 sections
A condensed version of the SIG Core questionnaire for lower-risk vendors, covering the most critical risk domains with fewer questions.
**Official source:** [Shared Assessments - SIG](https://sharedassessments.org/sig/)
* **Risk types:** Third-Party Risk, Information Security
* **Risk domains:** Vendor Due Diligence, Data Protection
* **Typical use cases:** Lower-risk vendor assessments; Annual reassessments of established vendors; Faster onboarding due diligence; Tiered vendor risk programs
* **Coverage:** 126 controls across 33 sections
Vendor Security Alliance (VSA) questionnaire 2025, a vendor security assessment covering cloud security, data management, and operational resilience.
**Official source:** [Vendor Security Alliance](https://www.vendorsecurityalliance.org/)
* **Risk types:** Third-Party Risk, Information Security, Operational Risk
* **Risk domains:** Vendor Due Diligence, Cloud Security, Operational Continuity
* **Typical use cases:** Vendor security program assessment; Cloud and SaaS vendor evaluation; VSA member organization compliance; Enterprise third-party risk management
* **Coverage:** 106 controls across 7 sections
## Compliance, privacy & payments
| Template | Controls | Focus | Official source |
| - | -: | - | - |
| Canadian CCSPA (Bill C-8) Third-Party Requirements NEW | 42 | Regulatory Compliance, Third-Party Risk | [Bill C-8, Critical Cyber Systems Protection Act](https://www.parl.ca/DocumentViewer/en/45-1/bill/C-8/royal-assent) |
| CCPA/CPRA Standard Requirements | 23 | Data Privacy, Regulatory Compliance | [California OAG - CCPA](https://oag.ca.gov/privacy/ccpa) |
| China Data Compliance & Cross-Border Transfer (CSL / DSL / PIPL / HGR) NEW | 60 | Regulatory Compliance, Data Privacy | [Personal Information Protection Law of the People's Republic of China](http://www.npc.gov.cn/englishnpc/c23934/202112/1abd8829788946ecab270e469b13c39c.shtml) |
| COBIT 5 Foundation (2019) | 30 | Operational Risk, Regulatory Compliance | [ISACA - COBIT](https://www.isaca.org/resources/cobit) |
| Complementary User Entity Controls (SOC 2 TSC) NEW | 30 | Third-Party Risk, Information Security | [AICPA SOC 2 (Trust Services Criteria)](https://www.aicpa-cima.com/topic/audit-assurance/audit-and-assurance-greater-than-soc-2) |
| EU Sustainability Reporting & Value-Chain Due Diligence (CSRD, CSDDD, EUDR, CBAM) NEW | 57 | Regulatory Compliance, Third-Party Risk | [Directive (EU) 2024/1760 (Corporate Sustainability Due Diligence)](https://eur-lex.europa.eu/eli/dir/2024/1760/oj) |
| GDPR Special-Category Health Data Processor (Life Sciences) NEW | 60 | Data Privacy, Regulatory Compliance | [EU GDPR (Regulation 2016/679)](https://eur-lex.europa.eu/eli/reg/2016/679/oj) |
| GDPR Standard Requirements | 18 | Data Privacy, Regulatory Compliance | [EU GDPR (Regulation 2016/679)](https://eur-lex.europa.eu/eli/reg/2016/679/oj) |
| NIS 2 Directive (EU 2022/2555) Third-Party Requirements NEW | 64 | Regulatory Compliance, Third-Party Risk | [Directive (EU) 2022/2555 (NIS 2)](https://eur-lex.europa.eu/eli/dir/2022/2555/oj) |
| NIST SP 800-18 Rev 2 NEW | 39 | Regulatory Compliance, Information Security | [NIST SP 800-18 Rev 2](https://csrc.nist.gov/pubs/sp/800/18/r2/final) |
| PCI 3DS Core Security Standard NEW | 37 | Regulatory Compliance, Information Security | [PCI SSC - 3DS](https://www.pcisecuritystandards.org/document_library/?category=3ds) |
| PCI DSS (v3.2.1, Legacy) NEW | 89 | Regulatory Compliance, Information Security | [PCI SSC Document Library (legacy)](https://www.pcisecuritystandards.org/document_library/) |
| PCI DSS (v4.0) | 63 | Regulatory Compliance, Information Security | [PCI SSC Document Library](https://www.pcisecuritystandards.org/document_library/) |
| PCI DSS SAQ A NEW | 22 | Regulatory Compliance, Information Security | [PCI SSC - SAQs](https://www.pcisecuritystandards.org/document_library/?category=saqs) |
| PCI DSS SAQ A-EP NEW | 90 | Regulatory Compliance, Information Security | [PCI SSC - SAQs](https://www.pcisecuritystandards.org/document_library/?category=saqs) |
| PCI DSS SAQ B NEW | 40 | Regulatory Compliance, Information Security | [PCI SSC - SAQs](https://www.pcisecuritystandards.org/document_library/?category=saqs) |
| PCI DSS SAQ C NEW | 80 | Regulatory Compliance, Information Security | [PCI SSC - SAQs](https://www.pcisecuritystandards.org/document_library/?category=saqs) |
| PCI DSS SAQ D NEW | 130 | Regulatory Compliance, Information Security | [PCI SSC - SAQs](https://www.pcisecuritystandards.org/document_library/?category=saqs) |
| PCI DSS v4.0 (Comprehensive) NEW | 249 | Regulatory Compliance, Information Security | [PCI SSC Document Library](https://www.pcisecuritystandards.org/document_library/) |
| PCI PIN Security NEW | 33 | Regulatory Compliance, Information Security | [PCI SSC - PIN Security](https://www.pcisecuritystandards.org/document_library/?category=pin) |
| PCI Point-to-Point Encryption (P2PE) NEW | 38 | Regulatory Compliance, Information Security | [PCI SSC - P2PE](https://www.pcisecuritystandards.org/document_library/?category=p2pe) |
| PCI Software Security Framework (SSF) NEW | 40 | Regulatory Compliance, Information Security | [PCI SSC - Software Security Framework](https://www.pcisecuritystandards.org/document_library/?category=software_security) |
| SOC 2 Type II Standard Requirements | 18 | Audit Readiness, Information Security | [AICPA SOC 2 (Trust Services Criteria)](https://www.aicpa-cima.com/topic/audit-assurance/audit-and-assurance-greater-than-soc-2) |
| Third-Party Anti-Bribery & Anti-Corruption Due Diligence (FCPA / UK Bribery Act) NEW | 60 | Regulatory Compliance, Third-Party Risk | [DOJ Foreign Corrupt Practices Act](https://www.justice.gov/criminal/criminal-fraud/foreign-corrupt-practices-act) |
Supplier due diligence for Canadian designated operators under the Critical Cyber Systems Protection Act. Covers supply chain and third-party risk identification under section 9(1)(a), the duty to mitigate as soon as a risk is identified under section 15, incident notification fast enough for the 72 hour report to the Communications Security Establishment under section 17, material change notice under section 14, and the records section 30 requires.
**Official source:** [Bill C-8, Critical Cyber Systems Protection Act](https://www.parl.ca/DocumentViewer/en/45-1/bill/C-8/royal-assent)
* **Risk types:** Regulatory Compliance, Third-Party Risk, Information Security, Operational Risk
* **Risk domains:** Supply Chain, Vendor Due Diligence, Incident Response, Risk Governance, Resilience
* **Typical use cases:** Canadian designated operator supplier due diligence; CCSPA s. 9(1)(a) supply chain risk identification; CCSPA s. 15 third-party risk mitigation; Critical cyber system supplier onboarding; CCSPA s. 30 record keeping
* **Coverage:** 42 controls across 10 sections
California Consumer Privacy Act (CCPA) and California Privacy Rights Act (CPRA) requirements for businesses handling California residents' personal information.
**Official source:** [California OAG - CCPA](https://oag.ca.gov/privacy/ccpa)
* **Risk types:** Data Privacy, Regulatory Compliance
* **Risk domains:** Privacy Rights, Data Protection
* **Typical use cases:** California privacy law compliance; Consumer data rights assessment; Data service provider evaluation; US state privacy law alignment
* **Coverage:** 23 controls across 17 sections
Supplier due diligence on Chinese data exposure for a vendor, CRO, clinical site, distributor or affiliate that processes data in mainland China or moves it out: how the Cybersecurity Law, Data Security Law and PIPL layer, PIPL's lawful bases and separate consent, the three Article 38 transfer routes and the thresholds the 2024 cross-border Provisions set for each, important data and CIIO designation, the Human Genetic Resources approval and filing regime that binds clinical research, localisation in practice, government and foreign-authority data requests, and exit.
**Official source:** [Personal Information Protection Law of the People's Republic of China](http://www.npc.gov.cn/englishnpc/c23934/202112/1abd8829788946ecab270e469b13c39c.shtml)
* **Risk types:** Regulatory Compliance, Data Privacy, Third-Party Risk, Life Sciences
* **Risk domains:** Data Protection, Privacy Rights, Vendor Due Diligence, Pharmaceutical, Risk Governance
* **Typical use cases:** China CRO and clinical site data diligence; PIPL cross-border transfer route verification; Human genetic resources approval and filing evidence; China affiliate data localisation review; Distributor and agent personal information review
* **Coverage:** 60 controls across 12 sections
COBIT 5/2019 governance and management framework for enterprise IT, covering IT governance, risk management, and information systems controls.
**Official source:** [ISACA - COBIT](https://www.isaca.org/resources/cobit)
* **Risk types:** Operational Risk, Regulatory Compliance, Financial Controls
* **Risk domains:** Risk Governance, Operational Continuity
* **Typical use cases:** IT governance program assessment; Enterprise risk management alignment; IT audit readiness; SOX IT controls evaluation
* **Coverage:** 30 controls across 7 sections
The customer-side (user entity) controls a SOC 2 report assigns to the organizations that consume a service, organized to mirror the five Trust Services Criteria categories. Use it to track the shared-responsibility controls you must implement for a provider's SOC 2 controls to operate effectively.
**Official source:** [AICPA SOC 2 (Trust Services Criteria)](https://www.aicpa-cima.com/topic/audit-assurance/audit-and-assurance-greater-than-soc-2)
* **Risk types:** Third-Party Risk, Information Security, Regulatory Compliance
* **Risk domains:** Vendor Due Diligence, Data Protection, Risk Governance
* **Typical use cases:** SOC 2 shared-responsibility tracking; Vendor onboarding CUEC attestation; User-entity control self-assessment; Third-party SOC report review
* **Coverage:** 30 controls across 5 sections
Supplier due diligence across the EU sustainability regime as it now stands after the Omnibus I simplification package: CSRD and the revised ESRS of Delegated Regulation (EU) 2026/1563, the value-chain cap and the VSME ceiling in Delegated Regulation (EU) 2026/1560, the amended CSDDD risk-based duty with its deleted climate transition plan and civil liability provisions, EUDR plot-level data and due diligence statements on the amended 2026 and 2027 dates, and CBAM embedded-emissions data under the amended 50 tonne de minimis.
**Official source:** [Directive (EU) 2024/1760 (Corporate Sustainability Due Diligence)](https://eur-lex.europa.eu/eli/dir/2024/1760/oj)
* **Risk types:** Regulatory Compliance, Third-Party Risk, Operational Risk, Audit Readiness
* **Risk domains:** Supply Chain, Vendor Due Diligence, Risk Governance, Logistics, Manufacturing Quality
* **Typical use cases:** CSRD value-chain data collection from a supplier; Value-chain cap and VSME ceiling assessment; CSDDD chain-of-activities supplier onboarding; EUDR relevant-product and plot-level data request; CBAM embedded-emissions data collection from a non-EU installation
* **Coverage:** 57 controls across 13 sections
Due diligence for a processor handling special-category health, genetic or biometric data on our behalf in a life-sciences context: clinical trial data, patient-support programmes, real-world-evidence and registry vendors, genomic sequencing providers, medical-device telemetry and pharmacovigilance safety data. Covers the Article 9(2) condition relied on and Article 9(4) Member State derogations, the Article 28 processor terms clause by clause, Article 32 security and the pseudonymisation key, Article 33(2) notification to the controller, Chapter V transfers under the 2021 Standard Contractual Clauses, Article 89 research safeguards, and readiness for the European Health Data Space Regulation (EU) 2025/327.
**Official source:** [EU GDPR (Regulation 2016/679)](https://eur-lex.europa.eu/eli/reg/2016/679/oj)
* **Risk types:** Data Privacy, Regulatory Compliance, Third-Party Risk, Healthcare, Life Sciences
* **Risk domains:** Data Protection, Privacy Rights, Healthcare Compliance, Vendor Due Diligence, Risk Governance
* **Typical use cases:** CRO, central lab and eClinical vendor privacy diligence; Real-world-evidence and registry vendor onboarding; Genomic sequencing and biobank provider review; Medical-device telemetry and connected-device data review; Pharmacovigilance safety-data vendor review; Article 28 data processing agreement negotiation; Chapter V transfer impact assessment evidence pack
* **Coverage:** 60 controls across 14 sections
EU General Data Protection Regulation (GDPR) standard requirements covering lawful processing, data subject rights, controller obligations, and breach notification.
**Official source:** [EU GDPR (Regulation 2016/679)](https://eur-lex.europa.eu/eli/reg/2016/679/oj)
* **Risk types:** Data Privacy, Regulatory Compliance
* **Risk domains:** Privacy Rights, Data Protection
* **Typical use cases:** EU/EEA data privacy compliance; Data processor assessment; Privacy-by-design evaluation; GDPR vendor due diligence
* **Coverage:** 18 controls across 13 sections
Supplier due diligence for EU essential and important entities under the NIS 2 Directive. Structured on the thirteen technical and methodological requirements in the Annex to Implementing Regulation (EU) 2024/2690, so the supply chain title carries the four supplier selection criteria of point 5.1.2 and the eight contract requirements of point 5.1.4. Incident questions are tied to the 24 hour early warning in Article 23(4)(a), which runs from your own awareness rather than the supplier's.
**Official source:** [Directive (EU) 2022/2555 (NIS 2)](https://eur-lex.europa.eu/eli/dir/2022/2555/oj)
* **Risk types:** Regulatory Compliance, Third-Party Risk, Information Security, Operational Risk
* **Risk domains:** Supply Chain, Vendor Due Diligence, Incident Response, Risk Governance, Resilience, Network Security, Identity & Access Management, Data Protection
* **Typical use cases:** EU essential or important entity supplier due diligence; NIS 2 Art. 21(2)(d) supply chain security; NIS 2 Art. 21(3) direct supplier risk assessment; ICT supplier and managed service provider onboarding; NIS 2 Art. 23 incident notification readiness
* **Coverage:** 64 controls across 14 sections
NIST SP 800-18 Revision 2, guidance for developing and maintaining system security, privacy, and cybersecurity supply-chain risk management (C-SCRM) plans that document a system's purpose, boundary, categorization, and selected controls across its life cycle.
**Official source:** [NIST SP 800-18 Rev 2](https://csrc.nist.gov/pubs/sp/800/18/r2/final)
* **Risk types:** Regulatory Compliance, Information Security, Operational Risk
* **Risk domains:** Risk Governance, Data Protection, Supply Chain
* **Typical use cases:** System security plan development; RMF authorization package preparation; Privacy and C-SCRM plan alignment; Federal system documentation review
* **Coverage:** 39 controls across 11 sections
The PCI 3DS Core Security Standard defines physical and logical security requirements for environments that perform EMV 3-D Secure (3DS) functions: the 3DS Server, 3DS Directory Server, and 3DS Access Control Server. It comprises Part 1 baseline security requirements and Part 2 3DS-specific requirements, and applies to entities that store, process, or transmit 3DS data or that could impact the security of 3DS transactions.
**Official source:** [PCI SSC - 3DS](https://www.pcisecuritystandards.org/document_library/?category=3ds)
* **Risk types:** Regulatory Compliance, Information Security, Financial Controls
* **Risk domains:** Data Protection, Network Security, Financial Reporting
* **Typical use cases:** EMV 3-D Secure environment security; 3DS Server / DS / ACS assessment; 3DS data and key management; Authentication service compliance
* **Coverage:** 37 controls across 12 sections
The prior major version of the Payment Card Industry Data Security Standard, retired in 2024 but retained for legacy audits and contracts that still reference v3.2.1. Use it for historical gap analysis and transition planning toward PCI DSS v4.0.
**Official source:** [PCI SSC Document Library (legacy)](https://www.pcisecuritystandards.org/document_library/)
* **Risk types:** Regulatory Compliance, Information Security, Financial Controls
* **Risk domains:** Financial Reporting, Data Protection, Network Security
* **Typical use cases:** Legacy PCI DSS v3.2.1 assessment; Contract referencing v3.2.1; Historical compliance gap analysis; Transition planning to v4.0
* **Coverage:** 89 controls across 12 sections
Payment Card Industry Data Security Standard v4.0, the security standard for organizations that handle cardholder data, updated with new authentication and monitoring requirements.
**Official source:** [PCI SSC Document Library](https://www.pcisecuritystandards.org/document_library/)
* **Risk types:** Regulatory Compliance, Information Security, Financial Controls
* **Risk domains:** Financial Reporting, Data Protection, Network Security
* **Typical use cases:** Payment processing compliance; Merchant security assessment; Card data environment evaluation; PCI QSA audit preparation
* **Coverage:** 63 controls across 12 sections
For card-not-present merchants (e-commerce or mail/telephone-order) that have fully outsourced all cardholder data functions to PCI DSS validated third parties, with no electronic storage, processing, or transmission of cardholder data on the merchant's systems.
**Official source:** [PCI SSC - SAQs](https://www.pcisecuritystandards.org/document_library/?category=saqs)
* **Risk types:** Regulatory Compliance, Information Security, Financial Controls
* **Risk domains:** Financial Reporting, Data Protection, Network Security
* **Typical use cases:** Fully outsourced e-commerce merchant; Mail/telephone-order (MOTO) merchant; No electronic cardholder data storage; All payment functions handled by validated third parties
* **Coverage:** 22 controls across 7 sections
For e-commerce merchants that partially outsource payment processing to a PCI DSS validated third party but whose own website can impact the security of the payment transaction, with no electronic storage of cardholder data on merchant systems.
**Official source:** [PCI SSC - SAQs](https://www.pcisecuritystandards.org/document_library/?category=saqs)
* **Risk types:** Regulatory Compliance, Information Security, Financial Controls
* **Risk domains:** Financial Reporting, Data Protection, Network Security
* **Typical use cases:** Partially outsourced e-commerce merchant; Merchant website impacts payment transactions; Direct-post or JavaScript-based payment integration; No electronic cardholder data storage
* **Coverage:** 90 controls across 12 sections
For merchants that process cardholder data only via imprint machines or standalone, dial-out payment terminals with no electronic cardholder data storage, and that do not transmit cardholder data over the internet.
**Official source:** [PCI SSC - SAQs](https://www.pcisecuritystandards.org/document_library/?category=saqs)
* **Risk types:** Regulatory Compliance, Information Security, Financial Controls
* **Risk domains:** Financial Reporting, Data Protection, Network Security
* **Typical use cases:** Imprint-machine merchant; Standalone dial-out terminal merchant; No internet-connected payment processing; No electronic cardholder data storage
* **Coverage:** 40 controls across 5 sections
For merchants with payment application systems connected to the internet (for example a POS system on a network with internet access) that do not electronically store cardholder data after a transaction is authorized.
**Official source:** [PCI SSC - SAQs](https://www.pcisecuritystandards.org/document_library/?category=saqs)
* **Risk types:** Regulatory Compliance, Information Security, Financial Controls
* **Risk domains:** Financial Reporting, Data Protection, Network Security
* **Typical use cases:** Payment application connected to the internet; Internet-connected POS environment; No electronic cardholder data storage; Segmented merchant location network
* **Coverage:** 80 controls across 11 sections
For all other merchants not addressed by SAQ types A through C, and for all service providers eligible to complete an SAQ. This SAQ covers substantially the full set of PCI DSS v4.0 requirements.
**Official source:** [PCI SSC - SAQs](https://www.pcisecuritystandards.org/document_library/?category=saqs)
* **Risk types:** Regulatory Compliance, Information Security, Financial Controls
* **Risk domains:** Financial Reporting, Data Protection, Network Security
* **Typical use cases:** Merchant storing cardholder data electronically; Service provider eligible for SAQ; Full-scope PCI DSS environment; Complex payment processing environment
* **Coverage:** 130 controls across 12 sections
Full defined-requirement-level coverage of PCI DSS v4.0 across all 12 requirements, with one control per numbered requirement for organizations that store, process, or transmit cardholder data. Intended for in-depth, QSA-grade assessment of the entire cardholder data environment.
**Official source:** [PCI SSC Document Library](https://www.pcisecuritystandards.org/document_library/)
* **Risk types:** Regulatory Compliance, Information Security, Financial Controls
* **Risk domains:** Financial Reporting, Data Protection, Network Security
* **Typical use cases:** Full PCI DSS v4.0 audit preparation; Level 1 merchant/service provider assessment; QSA-led compliance evaluation; Cardholder data environment deep review
* **Coverage:** 249 controls across 12 sections
The PCI PIN Security Requirements define controls for the secure management, processing, and transmission of personal identification number (PIN) data during online and offline payment transactions on ATMs and attended/unattended POS terminals. They apply to acquirers, processors, and any entity that manages PINs or the cryptographic keys used to protect them.
**Official source:** [PCI SSC - PIN Security](https://www.pcisecuritystandards.org/document_library/?category=pin)
* **Risk types:** Regulatory Compliance, Information Security, Financial Controls
* **Risk domains:** Data Protection, Network Security, Financial Reporting
* **Typical use cases:** PIN encryption and key management; ATM and POS terminal security; Cryptographic key lifecycle governance; Acquirer and processor PIN compliance
* **Coverage:** 33 controls across 7 sections
The PCI Point-to-Point Encryption (P2PE) Standard defines security requirements for solutions that encrypt account data at the point of interaction and decrypt it only within a secure environment, so that clear-text account data is never present in the merchant environment. It applies to P2PE solution providers, component providers, and merchants seeking to reduce PCI DSS scope through a validated P2PE solution.
**Official source:** [PCI SSC - P2PE](https://www.pcisecuritystandards.org/document_library/?category=p2pe)
* **Risk types:** Regulatory Compliance, Information Security, Financial Controls
* **Risk domains:** Data Protection, Network Security, Financial Reporting
* **Typical use cases:** Point-to-point encryption solution validation; POI device and key-injection management; Merchant PCI DSS scope reduction; Decryption environment (HSM) security
* **Coverage:** 38 controls across 6 sections
The PCI Software Security Framework comprises the Secure Software Standard and the Secure Software Lifecycle (Secure SLC) Standard, defining security requirements and assessment procedures for payment software and for the processes used to design, develop, and maintain it. It applies to software vendors and their payment software products, and is the successor to the legacy PA-DSS program.
**Official source:** [PCI SSC - Software Security Framework](https://www.pcisecuritystandards.org/document_library/?category=software_security)
* **Risk types:** Regulatory Compliance, Information Security, Financial Controls
* **Risk domains:** Data Protection, Network Security, Financial Reporting
* **Typical use cases:** Secure payment software validation; Secure software lifecycle governance; Software vulnerability and threat management; PA-DSS successor compliance
* **Coverage:** 40 controls across 20 sections
SOC 2 Type II standard requirements covering the Trust Services Criteria: Security, Availability, Processing Integrity, Confidentiality, and Privacy.
**Official source:** [AICPA SOC 2 (Trust Services Criteria)](https://www.aicpa-cima.com/topic/audit-assurance/audit-and-assurance-greater-than-soc-2)
* **Risk types:** Audit Readiness, Information Security, Regulatory Compliance
* **Risk domains:** Data Protection, Operational Continuity, Risk Governance
* **Typical use cases:** SOC 2 audit preparation; Customer security questionnaire responses; Service provider compliance verification; SaaS security due diligence
* **Coverage:** 18 controls across 1 sections
Due diligence for the intermediaries that carry the most corruption exposure: distributors, agents, resellers, customs brokers, freight forwarders, licence and permit consultants, joint-venture partners, lobbying and government-relations firms, and any supplier that deals with government officials or state-employed healthcare professionals on our behalf. Built on the FCPA anti-bribery provisions (15 U.S.C. 78dd-1, 78dd-2, 78dd-3) and accounting provisions (15 U.S.C. 78m(b)(2)), the UK Bribery Act 2010 including the section 7(2) adequate procedures defence, and the third-party management criteria in the DOJ Evaluation of Corporate Compliance Programs (Updated September 2024).
**Official source:** [DOJ Foreign Corrupt Practices Act](https://www.justice.gov/criminal/criminal-fraud/foreign-corrupt-practices-act)
* **Risk types:** Regulatory Compliance, Third-Party Risk, Financial Controls, Vendor Assessment, Audit Readiness
* **Risk domains:** Vendor Due Diligence, Risk Governance, Supply Chain, Financial Reporting, Healthcare Compliance
* **Typical use cases:** Distributor, agent and reseller onboarding; Customs broker and freight forwarder diligence; Joint-venture and consortium partner screening; Section 7(2) adequate procedures evidence pack; Government-official and state-employed HCP exposure review; Periodic re-certification of high-risk intermediaries
* **Coverage:** 60 controls across 12 sections
## Financial services & banking
For how these map onto the supervisory expectations themselves, stage by stage, see [Regulatory alignment for banks and credit unions](/security/regulatory-alignment).
| Template | Controls | Focus | Official source |
| - | -: | - | - |
| BSA/AML Standard Requirements | 35 | Regulatory Compliance, Financial Controls | [FinCEN - Bank Secrecy Act](https://www.fincen.gov/resources/statutes-and-regulations/bank-secrecy-act) |
| DORA Standard Requirements | 25 | Regulatory Compliance, Operational Risk | [EU DORA (Regulation 2022/2554)](https://eur-lex.europa.eu/eli/reg/2022/2554/oj) |
| FFIEC Contract Requirements | 30 | Regulatory Compliance, Third-Party Risk | [FFIEC IT Handbook - Outsourcing](https://ithandbook.ffiec.gov/it-booklets/outsourcing-technology-services/) |
| GLBA 16 CFR Part 313 | 20 | Regulatory Compliance, Data Privacy | [16 CFR Part 313 (eCFR)](https://www.ecfr.gov/current/title-16/chapter-I/subchapter-C/part-313) |
| Interagency Guidance on Risk Management (Full) | 156 | Regulatory Compliance, Third-Party Risk | [Interagency Guidance on Third-Party Relationships](https://www.federalregister.gov/documents/2023/06/09/2023-12340/interagency-guidance-on-third-party-relationships-risk-management) |
| Interagency Guidance on Risk Management (Lite) | 44 | Regulatory Compliance, Third-Party Risk | [Interagency Guidance on Third-Party Relationships](https://www.federalregister.gov/documents/2023/06/09/2023-12340/interagency-guidance-on-third-party-relationships-risk-management) |
| NCUA ISE (2023) | 30 | Regulatory Compliance, Information Security | [NCUA - Information Security Examination](https://ncua.gov/regulation-supervision/regulatory-compliance-resources/cybersecurity-resources/ncuas-information-security-examination-and-cybersecurity-assessment) |
| SOX COSO 2002 | 56 | Financial Controls, Regulatory Compliance | [COSO - Internal Control Framework](https://www.coso.org/guidance-on-ic) |
Bank Secrecy Act (BSA) and Anti-Money Laundering (AML) controls covering customer due diligence, suspicious activity reporting, and transaction monitoring.
**Official source:** [FinCEN - Bank Secrecy Act](https://www.fincen.gov/resources/statutes-and-regulations/bank-secrecy-act)
* **Risk types:** Regulatory Compliance, Financial Controls
* **Risk domains:** Banking & Finance, Financial Reporting
* **Typical use cases:** BSA/AML compliance program assessment; FinCEN regulatory alignment; Financial crime risk management; AML vendor evaluation
* **Coverage:** 35 controls across 24 sections
EU Digital Operational Resilience Act (DORA) controls for financial entities, covering ICT risk management, incident reporting, third-party risk, and resilience testing.
**Official source:** [EU DORA (Regulation 2022/2554)](https://eur-lex.europa.eu/eli/reg/2022/2554/oj)
* **Risk types:** Regulatory Compliance, Operational Risk, Third-Party Risk
* **Risk domains:** Resilience, Banking & Finance, Supply Chain
* **Typical use cases:** EU financial institution DORA compliance; ICT third-party risk assessment; Digital resilience program evaluation; Financial sector operational continuity
* **Coverage:** 25 controls across 6 sections
Federal Financial Institutions Examination Council (FFIEC) guidance on managing third-party service provider relationships for financial institutions.
**Official source:** [FFIEC IT Handbook - Outsourcing](https://ithandbook.ffiec.gov/it-booklets/outsourcing-technology-services/)
* **Risk types:** Regulatory Compliance, Third-Party Risk, Financial Controls
* **Risk domains:** Banking & Finance, Supply Chain, Risk Governance
* **Typical use cases:** Financial institution third-party oversight; Bank vendor due diligence; FFIEC regulatory compliance; Financial services outsourcing review
* **Coverage:** 30 controls across 13 sections
Gramm-Leach-Bliley Act (GLBA) Safeguards Rule (16 CFR Part 313) requirements for financial institutions protecting customer financial information.
**Official source:** [16 CFR Part 313 (eCFR)](https://www.ecfr.gov/current/title-16/chapter-I/subchapter-C/part-313)
* **Risk types:** Regulatory Compliance, Data Privacy, Financial Controls
* **Risk domains:** Banking & Finance, Data Protection
* **Typical use cases:** GLBA compliance for financial services; Customer financial data protection; Financial institution privacy program; FTC Safeguards Rule alignment
* **Coverage:** 20 controls across 3 sections
Detailed interagency guidance on third-party relationships for banking organizations, with controls across the full vendor lifecycle.
**Official source:** [Interagency Guidance on Third-Party Relationships](https://www.federalregister.gov/documents/2023/06/09/2023-12340/interagency-guidance-on-third-party-relationships-risk-management)
* **Risk types:** Regulatory Compliance, Third-Party Risk, Operational Risk
* **Risk domains:** Banking & Finance, Supply Chain, Risk Governance
* **Typical use cases:** Full-lifecycle bank vendor oversight; Critical third-party assessments; OCC/Fed/FDIC regulatory alignment; Senior management reporting on TPRM
* **Coverage:** 156 controls across 12 sections
Interagency guidance on third-party relationships for banking organizations, covering risk management expectations for vendor lifecycle management.
**Official source:** [Interagency Guidance on Third-Party Relationships](https://www.federalregister.gov/documents/2023/06/09/2023-12340/interagency-guidance-on-third-party-relationships-risk-management)
* **Risk types:** Regulatory Compliance, Third-Party Risk
* **Risk domains:** Banking & Finance, Supply Chain
* **Typical use cases:** Bank third-party risk program; Federal banking agency compliance; Vendor lifecycle risk management; Regulatory examination preparation
* **Coverage:** 44 controls across 13 sections
National Credit Union Administration (NCUA) Information Security Examination (ISE) program covering cybersecurity maturity for credit unions.
**Official source:** [NCUA - Information Security Examination](https://ncua.gov/regulation-supervision/regulatory-compliance-resources/cybersecurity-resources/ncuas-information-security-examination-and-cybersecurity-assessment)
* **Risk types:** Regulatory Compliance, Information Security
* **Risk domains:** Banking & Finance, Risk Governance
* **Typical use cases:** Credit union security examination; NCUA regulatory compliance; Credit union cybersecurity maturity; NCUA examination preparation
* **Coverage:** 30 controls across 17 sections
Sarbanes-Oxley Act (SOX) controls based on the COSO internal control framework, covering financial reporting accuracy and IT general controls for public companies.
**Official source:** [COSO - Internal Control Framework](https://www.coso.org/guidance-on-ic)
* **Risk types:** Financial Controls, Regulatory Compliance, Audit Readiness
* **Risk domains:** Financial Reporting, Risk Governance
* **Typical use cases:** SOX compliance program assessment; Public company internal controls review; IT general controls evaluation; External auditor readiness
* **Coverage:** 56 controls across 12 sections
## Healthcare & life sciences
| Template | Controls | Focus | Official source |
| - | -: | - | - |
| APAC GxP Manufacturing & Distribution (Japan, Australia, Singapore, China, India, Korea, Taiwan, ASEAN) NEW | 53 | Regulatory Compliance, Life Sciences | [Act on Securing Quality, Efficacy and Safety of Products Including Pharmaceuticals and Medical Devices](https://www.japaneselawtranslation.go.jp/en/laws/view/3213/en) |
| Certified & Accredited Supplier Verification (ISO 13485, ISO/IEC 17025, ISO 14971, ISO 15189) NEW | 55 | Regulatory Compliance, Audit Readiness | [ISO 13485:2016](https://www.iso.org/standard/59752.html) |
| Clinical Trial Service Provider Oversight (IND, IDE, ICH E6(R3), EU CTR) NEW | 75 | Regulatory Compliance, Life Sciences | [21 CFR Part 312 (Investigational New Drug Application)](https://www.ecfr.gov/current/title-21/chapter-I/subchapter-D/part-312) |
| EU Falsified Medicines Directive & Serialisation (2011/62/EU, DR 2016/161) NEW | 59 | Regulatory Compliance, Life Sciences | [Commission Delegated Regulation (EU) 2016/161](https://eur-lex.europa.eu/eli/reg_del/2016/161/oj) |
| EU GMP Outsourced Activities: Contract Acceptor Due Diligence NEW | 59 | Regulatory Compliance, Life Sciences | [EudraLex Volume 4 (EU GMP Guidelines)](https://health.ec.europa.eu/medicinal-products/eudralex/eudralex-volume-4_en) |
| EU Good Distribution Practice: Wholesale Distributor and Logistics Provider NEW | 59 | Regulatory Compliance, Life Sciences | [Guidelines on Good Distribution Practice (2013/C 343/01)](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A52013XC1123%2801%29) |
| EU MDR & IVDR Supply Chain Due Diligence (2017/745, 2017/746) NEW | 58 | Regulatory Compliance, Life Sciences | [Regulation (EU) 2017/745 (Medical Devices)](https://eur-lex.europa.eu/eli/reg/2017/745/oj) |
| FDA 21 CFR Part 11 & Data Integrity (Supplier-Hosted Systems) NEW | 45 | Regulatory Compliance, Life Sciences | [21 CFR Part 11 (Electronic Records; Electronic Signatures)](https://www.ecfr.gov/current/title-21/chapter-I/subchapter-A/part-11) |
| FDA Device QMSR Supplier Controls (21 CFR 820, ISO 13485) NEW | 51 | Regulatory Compliance, Life Sciences | [21 CFR Part 820 (Quality Management System Regulation)](https://www.ecfr.gov/current/title-21/chapter-I/subchapter-H/part-820) |
| FDA Drug cGMP & Contract Manufacturing (21 CFR 210/211) NEW | 58 | Regulatory Compliance, Life Sciences | [21 CFR Part 211 (cGMP for Finished Pharmaceuticals)](https://www.ecfr.gov/current/title-21/chapter-I/subchapter-C/part-211) |
| GxP Life Sciences | 83 | Life Sciences, Regulatory Compliance | [FDA - GxP Compliance](https://www.fda.gov/inspections-compliance-enforcement-and-criminal-investigations) |
| HIPAA Business Associate & Subcontractor Relationship NEW | 53 | Healthcare, Data Privacy | [45 CFR Part 164 (HIPAA Security and Privacy)](https://www.ecfr.gov/current/title-45/subtitle-A/subchapter-C/part-164) |
| HIPAA Standard Requirements | 42 | Healthcare, Data Privacy | [HHS - HIPAA Security Rule](https://www.hhs.gov/hipaa/for-professionals/security/index.html) |
| ICH, PIC/S and WHO Outsourcing & Supplier Quality NEW | 42 | Regulatory Compliance, Life Sciences | [ICH Quality Guidelines](https://www.ich.org/page/quality-guidelines) |
| Medical Device Cybersecurity & SBOM (FD\&C Act 524B) NEW | 47 | Information Security, Regulatory Compliance | [FD\&C Act section 524B (21 U.S.C. 360n-2)](https://www.govinfo.gov/app/details/USCODE-2023-title21/USCODE-2023-title21-chap9-subchapV-partA-sec360n-2) |
| Pharmacovigilance Service Provider (EU GVP & IR 520/2012) NEW | 59 | Regulatory Compliance, Life Sciences | [Commission Implementing Regulation (EU) No 520/2012](https://eur-lex.europa.eu/eli/reg_impl/2012/520/oj) |
| UK & Ireland GxP Supplier Oversight (MHRA / HPRA) NEW | 40 | Regulatory Compliance, Life Sciences | [Human Medicines Regulations 2012 (SI 2012/1916)](https://www.legislation.gov.uk/uksi/2012/1916/contents) |
| US Healthcare Fraud & Abuse: Suppliers and HCP-Engagement Intermediaries NEW | 58 | Regulatory Compliance, Healthcare | [OIG General Compliance Program Guidance](https://oig.hhs.gov/compliance/general-compliance-program-guidance/) |
Supplier due diligence for a manufacturer, marketing-authorisation partner, importer or distributor of medicines or devices across the major APAC regimes: Japan's PMD Act marketing authorisation holder system with GQP and GMP, Australian sponsorship and GMP clearance, Singapore dealer's licences and GDP, China's marketing authorisation holder and GSP distribution chain, India's import and manufacturing licences with revised Schedule M, and Korea, Taiwan and ASEAN at licence and standard level, plus cold chain, serialisation, local labelling, diversion, falsified product and recall coordination.
**Official source:** [Act on Securing Quality, Efficacy and Safety of Products Including Pharmaceuticals and Medical Devices](https://www.japaneselawtranslation.go.jp/en/laws/view/3213/en)
* **Risk types:** Regulatory Compliance, Life Sciences, Third-Party Risk, Audit Readiness
* **Risk domains:** Pharmaceutical, Manufacturing Quality, Logistics, Supply Chain, Vendor Due Diligence
* **Typical use cases:** APAC distributor and importer qualification; Japanese marketing authorisation holder partner diligence; TGA sponsor and GMP clearance evidence pack; China marketing authorisation holder and agent review; Multi-market cold chain and serialisation readiness
* **Coverage:** 53 controls across 12 sections
Supplier due diligence built on the certified and accredited management-system claims a life-sciences buyer relies on. Because ISO 13485:2016, ISO/IEC 17025:2017, ISO 14971:2019 and ISO 15189 are copyrighted standards this instrument does not quote, every control asks the supplier to evidence its claim: which certificate or accreditation is held, who issued it and under which recognition arrangement, exactly what the scope statement covers, whether the site and activity we buy fall inside it, the surveillance and nonconformity history, which test methods are on the schedule of accreditation, and the method validation, traceability, proficiency testing, uncertainty, impartiality, data integrity and notification arrangements behind them.
**Official source:** [ISO 13485:2016](https://www.iso.org/standard/59752.html)
* **Risk types:** Regulatory Compliance, Audit Readiness, Third-Party Risk, Life Sciences, Vendor Assessment
* **Risk domains:** Manufacturing Quality, Vendor Due Diligence, Supply Chain, Risk Governance, Healthcare Compliance
* **Typical use cases:** ISO 13485 certified supplier qualification; ISO/IEC 17025 testing and calibration laboratory approval; Contract laboratory scope-of-accreditation verification; Certificate and schedule-of-accreditation evidence pack; Annual requalification of a certified or accredited supplier
* **Coverage:** 55 controls across 14 sections
Service provider, CRO, site and eClinical vendor diligence across the three clinical regimes: the 21 CFR 312.52 written transfer of obligations and its silent-failure default, the absence of any equivalent under Part 812, ICH E6(R3)'s service-provider concept and its rule that untransferred activities stay with the sponsor, EU CTR delegation under Article 71 that never moves responsibility, and the safety, serious-breach and archiving clocks each regime sets in its own units.
**Official source:** [21 CFR Part 312 (Investigational New Drug Application)](https://www.ecfr.gov/current/title-21/chapter-I/subchapter-D/part-312)
* **Risk types:** Regulatory Compliance, Life Sciences, Third-Party Risk, Audit Readiness
* **Risk domains:** Pharmaceutical, Vendor Due Diligence, Healthcare Compliance, Data Protection, Risk Governance
* **Typical use cases:** CRO and service provider qualification; Central laboratory and eClinical vendor assessment; Transfer of obligations reconciliation; Safety reporting timeline verification; Trial master file and archiving review
* **Coverage:** 75 controls across 14 sections
Supplier due diligence on safety features across the EU supply chain: the unique identifier and its data carrier, the anti-tampering device, who applies the features and who uploads to the repositories system, the risk-based verification and decommissioning duties on wholesalers and on persons authorised to supply to the public, the suspected-falsification alert path, the 10-day reactivation window, equivalent identifiers on repackaged and parallel-distributed packs, and the upstream active-substance audit and registration duties.
**Official source:** [Commission Delegated Regulation (EU) 2016/161](https://eur-lex.europa.eu/eli/reg_del/2016/161/oj)
* **Risk types:** Regulatory Compliance, Life Sciences, Third-Party Risk, Audit Readiness
* **Risk domains:** Pharmaceutical, Supply Chain, Manufacturing Quality, Logistics, Vendor Due Diligence
* **Typical use cases:** Serialisation readiness of a contract packer or CMO; Wholesale distributor FMD verification assessment; Parallel importer and repackager qualification; Repository or serialisation IT provider diligence; Active-substance chain registration and audit evidence
* **Coverage:** 59 controls across 13 sections
Supplier due diligence for a Contract Acceptor performing outsourced GMP activities for an EU or EEA manufacturing authorisation holder or marketing authorisation holder: the Chapter 7 Contract Giver and Contract Acceptor split, the written contract and technical quality agreement, subcontracting and change control, Chapter 4 documentation and retention, Chapter 5 supplier qualification and active-substance supply-chain traceability, what the Qualified Person needs under Annex 16, unexpected deviations and quality defects, and reference and retention samples under Annex 19 as revised by C(2026) 4135 final.
**Official source:** [EudraLex Volume 4 (EU GMP Guidelines)](https://health.ec.europa.eu/medicinal-products/eudralex/eudralex-volume-4_en)
* **Risk types:** Regulatory Compliance, Life Sciences, Third-Party Risk, Audit Readiness
* **Risk domains:** Pharmaceutical, Manufacturing Quality, Supply Chain, Vendor Due Diligence, Healthcare Compliance
* **Typical use cases:** Contract manufacturing organisation qualification; Contract laboratory and contract analysis qualification; Technical quality agreement review; Qualified Person batch certification evidence pack; Active-substance supply-chain audit programme
* **Coverage:** 59 controls across 13 sections
Supplier due diligence for a wholesale distributor, contract logistics provider or broker handling medicinal products for human use in the EU or EEA, worked chapter by chapter through the Guidelines of 5 November 2013 on Good Distribution Practice (2013/C 343/01): quality system and risk management, the Responsible Person and their named duties, premises and temperature mapping, documentation, supplier and customer qualification, receipt and storage, picking, supply, destruction and export, complaints, returns, falsified products and recalls, outsourced activities, self-inspections, transport and in-transit excursions, brokers, plus the Article 80 wholesale-dealer duties and the Article 46b active-substance import duties of Directive 2001/83/EC.
**Official source:** [Guidelines on Good Distribution Practice (2013/C 343/01)](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A52013XC1123%2801%29)
* **Risk types:** Regulatory Compliance, Life Sciences, Third-Party Risk, Operational Risk, Audit Readiness
* **Risk domains:** Pharmaceutical, Logistics, Supply Chain, Vendor Due Diligence, Healthcare Compliance
* **Typical use cases:** Wholesale distributor qualification; Third-party logistics and cold-chain provider qualification; Responsible Person evidence pack; Broker registration and procedure check; GDP self-inspection and audit preparation
* **Coverage:** 59 controls across 14 sections
Supplier due diligence for a supplier, subcontractor, component manufacturer, authorised representative, importer or distributor in the supply chain of a medical device or in-vitro diagnostic placed on the EU market. Runs Regulation (EU) 2017/745 and Regulation (EU) 2017/746 in parallel and names where the two diverge: Article 10 general obligations and the quality management system, the Article 15 person responsible for regulatory compliance, Articles 11, 13, 14 and 16 economic-operator duties, UDI and EUDAMED, Annex I software and IT security with MDCG 2019-16, clinical and performance evaluation, post-market surveillance, the Article 87 / Article 82 vigilance clocks with the event type each one attaches to, and the Article 10a duty to give advance notice of an interruption or discontinuation of supply.
**Official source:** [Regulation (EU) 2017/745 (Medical Devices)](https://eur-lex.europa.eu/eli/reg/2017/745/oj)
* **Risk types:** Regulatory Compliance, Life Sciences, Third-Party Risk, Audit Readiness, Healthcare
* **Risk domains:** Manufacturing Quality, Supply Chain, Vendor Due Diligence, Healthcare Compliance, Risk Governance
* **Typical use cases:** MDR/IVDR critical supplier qualification; Authorised representative, importer and distributor due diligence; Contract manufacturer and sterilisation subcontractor onboarding; Medical device software and cybersecurity supplier review; Notified body audit readiness across the supply chain
* **Coverage:** 58 controls across 13 sections
Electronic records and signatures for a vendor-hosted or SaaS GxP system: the closed-system controls of 11.10, open-system controls of 11.30, signature requirements of 11.50 to 11.300, and the supplier-suitability, written-agreement and decommissioning expectations FDA set out in its October 2024 guidance on electronic systems in clinical investigations.
**Official source:** [21 CFR Part 11 (Electronic Records; Electronic Signatures)](https://www.ecfr.gov/current/title-21/chapter-I/subchapter-A/part-11)
* **Risk types:** Regulatory Compliance, Life Sciences, Information Security, Audit Readiness
* **Risk domains:** Data Protection, Identity & Access Management, Pharmaceutical, Vendor Due Diligence, Healthcare Compliance
* **Typical use cases:** eClinical and EDC vendor qualification; LIMS, MES and QMS software supplier assessment; Part 11 responsibility matrix for a hosted system; Data integrity (ALCOA+) supplier review; System decommissioning and data-exit planning
* **Coverage:** 45 controls across 10 sections
Device supplier diligence under the Quality Management System Regulation in force since 2 February 2026: the ISO 13485 bridge at 820.10(a), the written quality agreement that clause 4.1.5 now makes a binding US requirement, purchasing and verification under clause 7.4, the US-specific delta at 820.10(b) to Parts 803, 806, 830 and 821, the 820.35 and 820.45 record fields, and the withdrawal of the supplier-audit-report inspection exemption.
**Official source:** [21 CFR Part 820 (Quality Management System Regulation)](https://www.ecfr.gov/current/title-21/chapter-I/subchapter-H/part-820)
* **Risk types:** Regulatory Compliance, Life Sciences, Third-Party Risk, Audit Readiness
* **Risk domains:** Manufacturing Quality, Supply Chain, Vendor Due Diligence, Healthcare Compliance, Pharmaceutical
* **Typical use cases:** Device contract manufacturer qualification; Contract sterilizer and relabeler diligence; QMSR transition gap review against a pre-2026 checklist; Supplier change-notification agreement review; Combination product constituent-part supplier review
* **Coverage:** 51 controls across 12 sections
Contract manufacturer, contract packager and contract laboratory diligence under 21 CFR 210 and 211: the written quality agreement FDA's 2016 guidance expects, quality unit release under 211.22(a), the two-part test for relying on a supplier's test results under 211.84(d), investigation duties under 211.192 that reach other batches and other products, the 211.180 retention and location rules, and the field alert and adverse-event forwarding clocks.
**Official source:** [21 CFR Part 211 (cGMP for Finished Pharmaceuticals)](https://www.ecfr.gov/current/title-21/chapter-I/subchapter-C/part-211)
* **Risk types:** Regulatory Compliance, Life Sciences, Third-Party Risk, Audit Readiness
* **Risk domains:** Pharmaceutical, Manufacturing Quality, Supply Chain, Vendor Due Diligence, Healthcare Compliance
* **Typical use cases:** Contract manufacturing organisation qualification; Contract analytical laboratory diligence; Quality agreement gap review; API and excipient supplier approval; Pre-approval inspection readiness
* **Coverage:** 58 controls across 12 sections
Good Practice (GxP) controls for life sciences, covering GMP, GLP, and GCP requirements for pharmaceutical, biotech, and medical device companies.
**Official source:** [FDA - GxP Compliance](https://www.fda.gov/inspections-compliance-enforcement-and-criminal-investigations)
* **Risk types:** Life Sciences, Regulatory Compliance, Operational Risk
* **Risk domains:** Pharmaceutical, Data Protection
* **Typical use cases:** Pharma/biotech supplier qualification; FDA/EMA compliance assessment; Clinical trial data integrity; GxP-regulated vendor due diligence
* **Coverage:** 83 controls across 11 sections
Due diligence on the business associate relationship itself rather than the Security Rule safeguards: whether the supplier is a business associate at all, the provisions 45 CFR 164.504(e) and 164.314(a) require in the agreement, the flow-down duty to subcontractors, the breach notification clocks in 45 CFR 164.400-414, the individual rights the supplier has to support, return or destruction of PHI at termination, offshore access, the supplier's own direct liability under HITECH, and its readiness for the proposed Security Rule amendments.
**Official source:** [45 CFR Part 164 (HIPAA Security and Privacy)](https://www.ecfr.gov/current/title-45/subtitle-A/subchapter-C/part-164)
* **Risk types:** Healthcare, Data Privacy, Regulatory Compliance, Third-Party Risk
* **Risk domains:** Healthcare Compliance, Privacy Rights, Data Protection, Vendor Due Diligence, Incident Response
* **Typical use cases:** Business associate agreement negotiation and renewal; Covered entity vendor onboarding where PHI is disclosed; Business associate diligence on its own subcontractors; Breach notification readiness review; Termination and PHI disposition planning
* **Coverage:** 53 controls across 13 sections
Health Insurance Portability and Accountability Act (HIPAA) security and privacy rules covering administrative, physical, and technical safeguards for protected health information (PHI).
**Official source:** [HHS - HIPAA Security Rule](https://www.hhs.gov/hipaa/for-professionals/security/index.html)
* **Risk types:** Healthcare, Data Privacy, Regulatory Compliance
* **Risk domains:** Healthcare Compliance, Data Protection
* **Typical use cases:** HIPAA Business Associate assessment; Healthcare data security evaluation; PHI vendor due diligence; Healthcare compliance auditing
* **Coverage:** 42 controls across 10 sections
Risk-based supplier and outsourcing governance against the global standards: ICH Q10 section 2.7, Q9(R1) quality risk management, Q12 change communication across the supply chain, Q13 input-material control, the PIC/S PE 009 Chapter 7 Contract Giver model and Chapter 5 supplier qualification, and WHO TRS 986 Annex 2 contract production and supplier approval.
**Official source:** [ICH Quality Guidelines](https://www.ich.org/page/quality-guidelines)
* **Risk types:** Regulatory Compliance, Life Sciences, Third-Party Risk, Audit Readiness
* **Risk domains:** Pharmaceutical, Manufacturing Quality, Supply Chain, Vendor Due Diligence, Risk Governance
* **Typical use cases:** Contract manufacturer and contract laboratory qualification; ICH Q10 outsourced-activity governance evidence; PIC/S jurisdiction site assessment; WHO prequalification supply chain review; Excipient and API supplier risk assessment
* **Coverage:** 42 controls across 9 sections
Software and component supplier diligence for a cyber device: what the supplier must furnish for the sponsor to meet section 524B(b), software bill of materials depth and the two fields FDA adds beyond the NTIA baseline, coordinated vulnerability disclosure, notification and patch timelines back-solved from the sponsor's 30 and 60 day postmarket conditions, end-of-support and escrow, and the supplier's own update infrastructure as a related system.
**Official source:** [FD\&C Act section 524B (21 U.S.C. 360n-2)](https://www.govinfo.gov/app/details/USCODE-2023-title21/USCODE-2023-title21-chap9-subchapV-partA-sec360n-2)
* **Risk types:** Information Security, Regulatory Compliance, Life Sciences, Third-Party Risk
* **Risk domains:** Supply Chain, Threat Intelligence, Incident Response, Vendor Due Diligence, Healthcare Compliance
* **Typical use cases:** Device software and component supplier assessment; SBOM ingestion and depth review; Coordinated vulnerability disclosure readiness; End-of-support and source-code escrow negotiation; Premarket submission evidence gathering
* **Coverage:** 47 controls across 10 sections
Supplier due diligence on a vendor performing pharmacovigilance activities for a marketing authorisation holder: the safety data exchange agreement and the mandatory subcontract terms introduced by Implementing Regulation (EU) 2025/1466, onward subcontracting and written consent, the quality system and training, the QPPV and delegated tasks, what the vendor feeds into the pharmacovigilance system master file, case intake through day zero to the 15 and 90 day clocks, literature and digital-media screening, signal management, audit rights and the audit programme, inspection readiness under GVP Module III Rev 2, the safety database and business continuity, and retention and exit.
**Official source:** [Commission Implementing Regulation (EU) No 520/2012](https://eur-lex.europa.eu/eli/reg_impl/2012/520/oj)
* **Risk types:** Regulatory Compliance, Life Sciences, Third-Party Risk, Audit Readiness, Operational Risk
* **Risk domains:** Pharmaceutical, Healthcare Compliance, Vendor Due Diligence, Operational Continuity, Risk Governance
* **Typical use cases:** Pharmacovigilance service provider qualification; Safety data exchange agreement review; Adverse-event call centre and case-processing vendor diligence; Literature screening and signal detection vendor assessment; Pharmacovigilance inspection readiness of a subcontractor
* **Coverage:** 59 controls across 14 sections
Supplier due diligence for UK and Irish licence holders: the regulation 37(4) active-substance audit duty, the Responsible Person (import), Windsor Framework packaging and QP geography, UK GDP and GCP under ICH E6(R3) by dynamic reference, UK pharmacovigilance and the PSMF, and the points where an Irish site's EU obligations diverge from a GB site's retained ones.
**Official source:** [Human Medicines Regulations 2012 (SI 2012/1916)](https://www.legislation.gov.uk/uksi/2012/1916/contents)
* **Risk types:** Regulatory Compliance, Life Sciences, Third-Party Risk, Audit Readiness
* **Risk domains:** Pharmaceutical, Manufacturing Quality, Supply Chain, Vendor Due Diligence, Healthcare Compliance
* **Typical use cases:** MHRA licence holder supplier qualification; Active-substance manufacturer audit under HMR reg 37(4); Responsible Person (import) evidence pack; Windsor Framework packaging readiness; HPRA Irish site qualification
* **Coverage:** 40 controls across 9 sections
Third-party diligence on US healthcare fraud-and-abuse exposure for distributors, agencies, contract sales organisations, speaker-bureau and advisory-board managers, patient-support and hub vendors, charitable-foundation intermediaries and other HCP-engagement intermediaries: the Anti-Kickback Statute and the safe harbor relied on, Stark, the False Claims Act and the 60-day overpayment rule, Open Payments transfer-of-value data, exclusion and debarment screening, the OIG seven compliance elements, the voluntary industry codes and state marketing laws, and the government price-reporting and 340B points a vendor can touch.
**Official source:** [OIG General Compliance Program Guidance](https://oig.hhs.gov/compliance/general-compliance-program-guidance/)
* **Risk types:** Regulatory Compliance, Healthcare, Third-Party Risk, Life Sciences, Audit Readiness
* **Risk domains:** Healthcare Compliance, Vendor Due Diligence, Risk Governance, Pharmaceutical
* **Typical use cases:** Distributor, agency and contract sales organisation onboarding; Speaker bureau and advisory board vendor diligence; Patient support programme and hub vendor diligence; Charitable foundation and copay intermediary diligence; Open Payments data-feed assurance; Exclusion and debarment screening assurance
* **Coverage:** 58 controls across 14 sections
## AI governance
| Template | Controls | Focus | Official source |
| - | -: | - | - |
| AIUC-1 NEW | 51 | AI Risk, Information Security | [AIUC-1](https://www.aiuc-1.com) |
| CSA AICM 2025 | 243 | AI Risk, Information Security | [CSA AI Controls Matrix](https://cloudsecurityalliance.org/artifacts/ai-controls-matrix) |
| EU AI Act NEW | 22 | AI Risk, Regulatory Compliance | [Regulation (EU) 2024/1689](https://eur-lex.europa.eu/eli/reg/2024/1689/oj) |
| ISO/IEC 42001:2023 NEW | 38 | AI Risk, Regulatory Compliance | [ISO/IEC 42001:2023](https://www.iso.org/standard/81230.html) |
| MITRE ATLAS NEW | 14 | AI Risk, Information Security | [MITRE ATLAS](https://atlas.mitre.org/) |
| NIST AI RMF 2.0 | 72 | AI Risk, Operational Risk | [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework) |
| NIST SP 800-53 AI Risk Management | 17 | AI Risk, Information Security | [NIST SP 800-53 Rev 5](https://csrc.nist.gov/pubs/sp/800/53/r5/upd1/final) |
| OWASP Top 10 for LLM Applications (2025) NEW | 10 | AI Risk, Information Security | [OWASP Top 10 for LLM Apps](https://genai.owasp.org/llm-top-10/) |
AIUC-1, the AI Usage & Controls standard for AI agents, covering security, safety, reliability, data & privacy, accountability, and societal risk. Its 51 controls span six domains (A Data & Privacy, B Security, C Safety, D Reliability, E Accountability, F Society) and crosswalk to the EU AI Act, NIST AI RMF, ISO/IEC 42001, MITRE ATLAS, and OWASP.
**Official source:** [AIUC-1](https://www.aiuc-1.com)
* **Risk types:** AI Risk, Information Security, Third-Party Risk, Regulatory Compliance
* **Risk domains:** AI Governance, Data Protection
* **Typical use cases:** AI agent vendor due diligence; AI safety and security assessment; Generative AI supplier evaluation; AI governance readiness
* **Coverage:** 51 controls across 6 sections
Cloud Security Alliance AI Controls Matrix (AICM) 2025, a framework of security controls specifically designed for AI/ML systems and platforms.
**Official source:** [CSA AI Controls Matrix](https://cloudsecurityalliance.org/artifacts/ai-controls-matrix)
* **Risk types:** AI Risk, Information Security, Regulatory Compliance
* **Risk domains:** AI Governance, Cloud Security, Data Protection
* **Typical use cases:** AI/ML platform security assessment; Cloud AI vendor evaluation; AI security controls gap analysis; Emerging AI regulatory alignment
* **Coverage:** 243 controls across 19 sections
EU AI Act (Regulation (EU) 2024/1689), the European Union's horizontal regulation for artificial intelligence. This template organizes the Act's core obligations by theme: prohibited practices, risk classification, high-risk system requirements, provider and deployer duties, transparency, general-purpose AI models, and post-market governance.
**Official source:** [Regulation (EU) 2024/1689](https://eur-lex.europa.eu/eli/reg/2024/1689/oj)
* **Risk types:** AI Risk, Regulatory Compliance, Data Privacy
* **Risk domains:** AI Governance, Risk Governance
* **Typical use cases:** EU AI Act readiness assessment; High-risk AI system conformity review; AI vendor regulatory due diligence; GPAI model obligation mapping
* **Coverage:** 22 controls across 8 sections
ISO/IEC 42001:2023, the international management-system standard for artificial intelligence (AIMS). This template covers the Annex A reference controls across nine control objectives, from AI policy and impact assessment to data governance and third-party relationships.
**Official source:** [ISO/IEC 42001:2023](https://www.iso.org/standard/81230.html)
* **Risk types:** AI Risk, Regulatory Compliance, Audit Readiness
* **Risk domains:** AI Governance, Risk Governance
* **Typical use cases:** AI management system (AIMS) assessment; ISO/IEC 42001 readiness and gap analysis; AI vendor due diligence; Responsible AI program evaluation
* **Coverage:** 38 controls across 9 sections
MITRE ATLAS (Adversarial Threat Landscape for Artificial-Intelligence Systems), a knowledge base of adversary tactics and techniques against AI/ML systems, modeled on MITRE ATT\&CK. This template turns the ATLAS tactics into a defensive assessment of a vendor's resilience to adversarial machine-learning attacks.
**Official source:** [MITRE ATLAS](https://atlas.mitre.org/)
* **Risk types:** AI Risk, Information Security, Third-Party Risk
* **Risk domains:** AI Governance, Threat Intelligence
* **Typical use cases:** Adversarial ML threat assessment; AI/ML security vendor evaluation; AI red-team and threat-model scoping; AI supply-chain security review
* **Coverage:** 14 controls across 1 section
NIST AI Risk Management Framework (AI RMF 1.0), a voluntary framework for managing risks of AI systems across four core functions: Govern, Map, Measure, and Manage.
**Official source:** [NIST AI Risk Management Framework](https://www.nist.gov/itl/ai-risk-management-framework)
* **Risk types:** AI Risk, Operational Risk, Regulatory Compliance
* **Risk domains:** AI Governance, Risk Governance
* **Typical use cases:** AI system risk assessment; Responsible AI program evaluation; AI vendor due diligence; AI governance readiness
* **Coverage:** 72 controls across 4 sections
NIST SP 800-53 controls adapted for AI systems, a catalog of security and privacy controls for AI risk management in federal and enterprise contexts.
**Official source:** [NIST SP 800-53 Rev 5](https://csrc.nist.gov/pubs/sp/800/53/r5/upd1/final)
* **Risk types:** AI Risk, Information Security, Regulatory Compliance
* **Risk domains:** AI Governance, Risk Governance, Data Protection
* **Typical use cases:** Federal AI system compliance; AI risk control catalog alignment; Enterprise AI security program; FedRAMP-adjacent AI assessments
* **Coverage:** 17 controls across 4 sections
OWASP Top 10 for Large Language Model Applications (2025), the ten most critical security risks for LLM and generative-AI applications, from prompt injection and sensitive-information disclosure to excessive agency and unbounded consumption. Used to assess the security posture of AI/LLM vendors.
**Official source:** [OWASP Top 10 for LLM Apps](https://genai.owasp.org/llm-top-10/)
* **Risk types:** AI Risk, Information Security, Third-Party Risk
* **Risk domains:** AI Governance, Data Protection
* **Typical use cases:** LLM application security assessment; Generative AI vendor security review; AI red-team scoping; Secure AI development gap analysis
* **Coverage:** 10 controls across 1 section
## Operations & supply chain
Five templates for suppliers of physical goods and services, where the risk is a stopped production line rather than a breach. Each is organised into six sections covering the supplier lifecycle from planning through verification. Unlike the frameworks above, these are written by Coverbase rather than derived from a single published standard, so they cite no external source. Individual controls do reference standards where one applies, such as ISO 9001 for quality systems or EU 10/2011 for food contact materials.
| Template | Controls | Focus | |
| - | -: | - | - |
| Contract Manufacturing Oversight NEW | 25 | Operational Risk, Third-Party Risk, Audit Readiness | |
| Logistics and Distribution Partner NEW | 24 | Operational Risk, Third-Party Risk | |
| Packaging and Product Compliance NEW | 23 | Regulatory Compliance, Operational Risk | |
| Raw Material and Chemical Supply Integrity NEW | 25 | Operational Risk, Regulatory Compliance, Third-Party Risk | |
| Responsible Minerals & Conflict Minerals (3TG, Cobalt, Mica) NEW | 49 | Third-Party Risk, Regulatory Compliance | [Regulation (EU) 2017/821 (Conflict Minerals)](https://eur-lex.europa.eu/eli/reg/2017/821/oj) |
| Supplier Resilience and Continuity NEW | 27 | Operational Risk, Third-Party Risk | |
Oversight of a third party building your product. Covers quality system scope at the producing site, change control and which changes need your approval, undisclosed onward subcontracting, batch traceability, non-conformance handling and who may release held product, and capacity and customer-owned tooling. Backward traceability alone does not bound a recall, so it also asks the forward question: given a suspect input lot, which finished units contain it.
* **Risk types:** Operational Risk, Third-Party Risk, Audit Readiness
* **Risk domains:** Manufacturing Quality, Supply Chain, Vendor Due Diligence
* **Typical use cases:** Contract manufacturer onboarding; Toll processing oversight; Private label supplier qualification
* **Sections:** Quality management system, Change control, Subcontracting, Traceability and records, Non-conformance and corrective action, Capacity and tooling
* **Coverage:** 25 controls across 6 sections
Freight forwarders, carriers and third-party logistics providers. Covers cargo cover set against the governing liability convention, chain of custody and seal integrity, condition monitoring and excursion reporting, the named list of facilities that will hold your goods, contingency routing and peak capacity, and trade compliance. Insurance limits and convention caps are asked separately, because the gap between the two is where your exposure sits.
* **Risk types:** Operational Risk, Third-Party Risk
* **Risk domains:** Logistics, Supply Chain, Operational Continuity
* **Typical use cases:** 3PL onboarding; Freight forwarder review; Cold chain partner qualification
* **Sections:** Coverage and liability, Chain of custody, Condition control, Network and facilities, Contingency, Trade compliance
* **Coverage:** 24 controls across 6 sections
Converters and packaging suppliers. Covers product contact compliance across the markets you sell into, declarations of compliance and what triggers a reissue, recycled content substantiation and whether a claim is physical or mass balance, the data behind packaging waste reporting, migration testing conditions, and recall support. Recycled content in a product contact layer usually needs its own authorisation, which a general recycled claim does not provide.
* **Risk types:** Regulatory Compliance, Operational Risk
* **Risk domains:** Manufacturing Quality, Risk Governance, Supply Chain
* **Typical use cases:** Packaging supplier qualification; Product contact compliance; Packaging waste reporting readiness
* **Sections:** Product contact compliance, Declarations and change management, Sustainability claims, Extended producer responsibility, Testing and verification, Recall and incident support
* **Coverage:** 23 controls across 6 sections
Resin, chemical and commodity inputs. Covers certificates of analysis issued against an agreed specification, composition disclosure including substances below reportable thresholds, restricted substance and PFAS declarations, regulatory change monitoring, country of origin and lot traceability, responsible sourcing and forced labour risk, and shelf life and retained samples. Undisclosed blending across sources breaks the link between certificate and delivery, so it is asked directly.
* **Risk types:** Operational Risk, Regulatory Compliance, Third-Party Risk
* **Risk domains:** Supply Chain, Risk Governance
* **Typical use cases:** Raw material supplier qualification; Restricted substance diligence; Responsible sourcing review
* **Sections:** Specification and certification, Composition and restricted substances, Regulatory monitoring, Origin and traceability, Responsible sourcing, Handling and stability
* **Coverage:** 25 controls across 6 sections
Supplier due diligence on conflict minerals and responsible mineral sourcing for components, devices, packaging and equipment containing tin, tantalum, tungsten, gold, cobalt or mica: Dodd-Frank section 1502 and SEC Rule 13p-1 with Form SD, Regulation (EU) 2017/821 for Union importers, the OECD five-step framework and its Annex II risks, CMRT and EMRT completeness and declaration scope, smelter and refiner conformance, chain-of-custody claims, and the forced and child labour obligations a buyer bundles with them.
**Official source:** [Regulation (EU) 2017/821 (Conflict Minerals)](https://eur-lex.europa.eu/eli/reg/2017/821/oj)
* **Risk types:** Third-Party Risk, Regulatory Compliance, Operational Risk, Vendor Assessment
* **Risk domains:** Supply Chain, Vendor Due Diligence, Risk Governance, Manufacturing Quality
* **Typical use cases:** Conflict minerals survey of a component or device supplier; CMRT and EMRT review before a Form SD filing; Union importer due diligence under Regulation (EU) 2017/821; Smelter and refiner conformance gap closure; Forced labour and UFLPA traceability screening
* **Coverage:** 49 controls across 11 sections
Whether a supplier can keep your line fed, and what happens when it cannot. Covers continuity planning and annual testing, recovery objectives, alternate sites and the lead time to qualify one, ownership and transfer of customer tooling, lead time and buffer stock, sub-tier visibility and geographic concentration, and how constrained supply is allocated across customers. Asks for a dated continuity test rather than the existence of a plan, and treats an alternate source the supplier cannot name as no alternate at all.
* **Risk types:** Operational Risk, Third-Party Risk
* **Risk domains:** Operational Continuity, Supply Chain, Resilience
* **Typical use cases:** Production-critical supplier review; Single-source exposure; Business continuity due diligence
* **Sections:** Continuity planning, Alternate sourcing and capacity, Lead time and inventory, Upstream dependency, Disruption response, Verification
* **Coverage:** 27 controls across 6 sections
# Internal Controls Library
The 22 templates below are evaluated against **your own** applications, not a vendor's. [Coverbase Inspect](/products/agentic-inspect) signs in to the application with read-only credentials, drives its admin console, and decides each control from what it can see.
These controls are written for an agent rather than a person. Each one states an expectation carrying its own threshold, names the admin surface to look at plus the alternate labels other vendors use for it, and defines what counts as **incomplete**. Incomplete is a real outcome, not a failure: an application that does not sell a capability cannot fail a control about it. Every control also forbids destructive or outbound actions, so a run reads state and never changes it.
Start with **Security Configuration Baseline** on a newly onboarded application, then layer a domain set on top. It is deliberately vendor-neutral and short enough to run against the long tail of niche tools that will never justify a bespoke control set.
## Identity and access
| Template | Controls | Focus |
| - | -: | - |
| Identity & Authentication Baseline | 22 | Information Security, Operational Risk |
| Privileged & Administrative Access | 18 | Information Security, Operational Risk |
| Application Access Lifecycle | 15 | Information Security, Operational Risk |
How workforce users sign in to an application, read from the live admin console rather than from an attestation. Covers MFA enforcement and its exceptions, SSO federation and whether the local login form survives beside it, password and session policy, and the authentication events the tenant keeps. Written for continuous Inspect runs: every expectation carries its own threshold so a run can decide it without asking anyone.
* **Risk types:** Information Security, Operational Risk
* **Risk domains:** Identity & Access Management
* **Typical use cases:** Continuous verification that MFA is enforced, not merely available; Detecting authentication policy drift between assessments; Evidence that SSO enforcement survived a tenant migration; Pre-contract validation of a SaaS application's login controls
* **Coverage:** 22 controls across 4 sections
Who holds administrative power inside an application right now, and what bounds it. Counts and names administrators from the live member list, checks whether privilege is standing or requested, and looks for the break-glass, service, and API principals that ordinary access reviews miss. Sized so an Inspect run can complete it against most admin consoles in one session.
* **Risk types:** Information Security, Operational Risk, Audit Readiness
* **Risk domains:** Identity & Access Management, Risk Governance
* **Typical use cases:** Continuous administrator-count monitoring between access reviews; Detecting privilege creep in a high-risk SaaS application; Evidence for a SOX or SOC 2 access-review control; Finding service and break-glass accounts nobody owns
* **Coverage:** 18 controls across 4 sections
Joiner, mover and leaver evidence read from inside the application rather than from the HR system that is supposed to drive it. Finds the accounts that outlived their owner, the invitations nobody accepted, the external collaborators still holding a seat, and the offboarding steps that stop at the identity provider and never reach the app.
* **Risk types:** Information Security, Operational Risk, Audit Readiness
* **Risk domains:** Identity & Access Management, Risk Governance
* **Typical use cases:** Continuous leaver-account detection between HR and SaaS; Evidence that offboarding reached every in-scope application; Finding dormant seats before a renewal negotiation; Access-review support for an audited application
* **Coverage:** 15 controls across 4 sections
## Application scope and integrations
| Template | Controls | Focus |
| - | -: | - |
| Application Scope & Feature Drift | 13 | Third-Party Risk, Operational Risk |
| Integrations, OAuth & Connected Apps | 18 | Information Security, Third-Party Risk |
| Security Configuration Baseline | 16 | Information Security, Operational Risk |
| Usage, Seats & Licensing | 12 | Financial Controls, Operational Risk |
What an application is being used for today, checked against what it was approved for. An assessment scopes a vendor once; the vendor then ships features, an admin turns one on, and the application quietly starts touching data or performing functions nobody vetted. These controls read the live feature and module state so a re-inspection surfaces the drift as a diff.
* **Risk types:** Third-Party Risk, Operational Risk, Regulatory Compliance
* **Risk domains:** Vendor Due Diligence, Risk Governance
* **Typical use cases:** Detecting features enabled after the vendor was assessed; Confirming an application stayed inside its approved use case; Re-scoping trigger for an annual vendor review; Shadow-module discovery inside an approved application
* **Coverage:** 13 controls across 3 sections
The fourth-party surface an application accumulates. Every OAuth grant, installed app, webhook and inbound connection is a path for data to leave the tenant, and most of them were authorised by an individual user rather than through a review. These controls enumerate the connections, read their scopes, and check whether an administrator ever has to approve one.
* **Risk types:** Information Security, Third-Party Risk, Data Privacy
* **Risk domains:** Supply Chain, Data Protection, Identity & Access Management
* **Typical use cases:** Fourth-party discovery inside an approved application; OAuth scope review for a data-bearing SaaS tenant; Detecting user-authorised integrations that bypassed review; Shadow-integration monitoring between assessments
* **Coverage:** 18 controls across 4 sections
The settings any business application should hold regardless of what it does. Deliberately vendor-neutral and short enough to run against every application in an estate, including the long tail of niche tools that will never justify a bespoke control set of their own. Use it as the default set for a newly onboarded application and layer a domain set on top.
* **Risk types:** Information Security, Operational Risk
* **Risk domains:** Identity & Access Management, Data Protection
* **Typical use cases:** Default control set for every newly onboarded application; Baseline coverage across the long tail of niche SaaS tools; Configuration drift detection between assessments; Fast first Inspect run on an unfamiliar application
* **Coverage:** 16 controls across 3 sections
What the organization is paying for against what it is using. Seat waste, unassigned licences, dormant accounts and shadow expansion are financial findings that happen to be readable from the same admin surfaces as the security ones, so a run that is already logged in should collect them.
* **Risk types:** Financial Controls, Operational Risk, Third-Party Risk
* **Risk domains:** Vendor Due Diligence, Risk Governance
* **Typical use cases:** Seat utilisation evidence ahead of a renewal negotiation; Detecting licence expansion between contract reviews; Finding dormant paid seats across an estate; Reconciling contracted entitlement against deployed configuration
* **Coverage:** 12 controls across 2 sections
## Data handling and privacy
| Template | Controls | Focus |
| - | -: | - |
| Data Services & Storage Surface | 13 | Information Security, Operational Risk |
| PII Data Scope & Handling | 16 | Data Privacy, Regulatory Compliance |
| Retention, Residency & Deletion | 15 | Data Privacy, Regulatory Compliance |
| Export, Sharing & External Collaboration | 16 | Information Security, Data Privacy |
| PHI & HIPAA Application Safeguards | 21 | Regulatory Compliance, Data Privacy |
| GDPR & Cross-Border Privacy | 22 | Data Privacy, Regulatory Compliance |
The storage, encryption, backup and key-management state an application exposes to its tenant. Most of this is the vendor's to configure, but the parts a tenant owns (customer-managed keys, backup schedules, storage region, attachment handling) drift silently and are exactly what a SOC 2 report will not tell you about this tenant on this day.
* **Risk types:** Information Security, Operational Risk
* **Risk domains:** Data Protection, Cloud Security
* **Typical use cases:** Verifying customer-managed encryption keys are still bound to the tenant; Confirming backup configuration between assessments; Storage region validation for a data-residency commitment; Evidence for an encryption-at-rest control
* **Coverage:** 13 controls across 3 sections
Which categories of personal data an application holds, established from field names, object schemas and data-classification surfaces rather than from a questionnaire. Includes the masking, minimisation and subject-rights machinery a privacy programme depends on. Every instruction reads metadata: Inspect establishes that a field exists, never what any individual's value is.
* **Risk types:** Data Privacy, Regulatory Compliance, Information Security
* **Risk domains:** Data Protection, Privacy Rights
* **Typical use cases:** Continuous PII inventory for a records-of-processing obligation; Detecting personal data appearing in an application never scoped for it; Evidence that masking is applied to identifiers in a support tool; Privacy review of a newly onboarded SaaS application
* **Coverage:** 16 controls across 4 sections
Where data sits, how long it stays, and what happens when somebody deletes it. These are contractual and regulatory commitments that live as tenant settings, which means they can be changed by an administrator without anyone renegotiating the contract, and a point-in-time assessment would never notice.
* **Risk types:** Data Privacy, Regulatory Compliance, Operational Risk
* **Risk domains:** Data Protection, Privacy Rights
* **Typical use cases:** Verifying a contractual data-residency commitment still holds; Retention-policy drift detection between audits; Evidence for a records-management control; Confirming deletion reaches backups and logs
* **Coverage:** 15 controls across 3 sections
Every way data leaves an application through a route the application itself provides: public links, external sharing, downloads, bulk exports, printing and email forwarding. These settings are changed by administrators for good operational reasons and are almost never revisited, which is what makes them worth reading on every run rather than once a year.
* **Risk types:** Information Security, Data Privacy, Operational Risk
* **Risk domains:** Data Protection
* **Typical use cases:** Continuous monitoring of external sharing defaults; Finding public links created before a policy tightened; Evidence for a data-loss-prevention control; Egress review of a collaboration application
* **Coverage:** 16 controls across 4 sections
The HIPAA Security Rule technical safeguards, expressed as things an agent can read from a live application rather than as policy language. Covers unique user identification, emergency access, automatic logoff, audit controls, transmission security and the minimum-necessary access standard. Written for covered entities and business associates running clinical, claims or patient- facing SaaS.
* **Risk types:** Regulatory Compliance, Data Privacy, Healthcare
* **Risk domains:** Healthcare Compliance, Data Protection, Identity & Access Management
* **Typical use cases:** Continuous HIPAA Security Rule evidence for an in-scope application; Detecting PHI appearing in an application with no BAA; Minimum-necessary access verification between audits; Business associate application monitoring
* **Coverage:** 21 controls across 4 sections
GDPR obligations that are configuration rather than paperwork: where personal data sits, who processes it, what the tenant can produce for a subject request, how long records live, and which transfers leave the EEA. Read from the live application so the record of processing reflects the tenant as configured today rather than as described at onboarding.
* **Risk types:** Data Privacy, Regulatory Compliance
* **Risk domains:** Privacy Rights, Data Protection
* **Typical use cases:** Keeping an Article 30 record of processing accurate between reviews; Verifying an international transfer commitment still holds; Establishing that subject-rights requests can be served; Privacy review of an EEA-facing SaaS application
* **Coverage:** 22 controls across 4 sections
## AI usage
| Template | Controls | Focus |
| - | -: | - |
| AI Features & Model Usage | 23 | AI Risk, Data Privacy |
| AI Agents, Copilots & Autonomous Actions | 17 | AI Risk, Information Security |
The AI surface a vendor has switched on inside an application. This is the fastest-drifting scope in any SaaS estate: features arrive enabled by default in a release the tenant did not choose, they read whatever the application holds, and they route it to a model the assessment never named. These controls enumerate what is on, what it reads, where it sends, and whether tenant data trains anything.
* **Risk types:** AI Risk, Data Privacy, Third-Party Risk, Information Security
* **Risk domains:** AI Governance, Data Protection, Supply Chain
* **Typical use cases:** Detecting AI features enabled by a vendor release nobody reviewed; Establishing whether tenant data trains a vendor model; AI inventory for an EU AI Act or ISO 42001 obligation; Continuous monitoring of an application's AI scope
* **Coverage:** 23 controls across 4 sections
AI that acts rather than answers. An agent configured inside an application holds a standing identity, a set of tools, and permission to write, which makes it a privileged principal that no access review lists and no joiner process created. These controls enumerate the agents, read what they may do, and check whether their actions are attributable and reversible.
* **Risk types:** AI Risk, Information Security, Operational Risk
* **Risk domains:** AI Governance, Identity & Access Management
* **Typical use cases:** Inventorying autonomous agents operating inside a business application; Establishing what an agent is permitted to write and to whom it can send; Attribution evidence for actions taken by an AI agent; Continuous monitoring of agent scope expansion
* **Coverage:** 17 controls across 3 sections
## Resilience, performance and audit
| Template | Controls | Focus |
| - | -: | - |
| Operational Resilience & Failover | 21 | Operational Risk, Third-Party Risk |
| Performance & SLA Conformance | 14 | Operational Risk, Third-Party Risk |
| Audit Logging & Monitoring | 13 | Information Security, Audit Readiness |
Resilience evidence gathered from inside a live application on an ordinary working day, rather than from a scheduled Saturday failover test the vendor agreed to in advance. Reads the tenant's own status, incident, maintenance and capacity surfaces, and records the observations that only mean something as a series: which instance served the run, what the response looked like, whether the data present today matches yesterday.
* **Risk types:** Operational Risk, Third-Party Risk, Regulatory Compliance
* **Risk domains:** Operational Continuity, Resilience
* **Typical use cases:** Continuous third-party resilience testing without vendor coordination; Regulatory evidence for an operational resilience programme; Detecting an unannounced failover or instance migration; Building an uptime record independent of the vendor's own status page
* **Coverage:** 21 controls across 4 sections
Whether the service the tenant is receiving matches the service that was contracted. Reads the uptime figures, support response commitments, credit mechanisms and observed responsiveness that together answer 'did they meet the SLA', a question most organizations can only ask retrospectively, from the vendor's own numbers.
* **Risk types:** Operational Risk, Third-Party Risk, Financial Controls
* **Risk domains:** Operational Continuity, Vendor Due Diligence
* **Typical use cases:** Independent SLA conformance evidence for a renewal negotiation; Continuous uptime measurement not sourced from the vendor; Service credit eligibility detection; Support responsiveness monitoring for a critical application
* **Coverage:** 14 controls across 3 sections
Whether an application can tell you what happened in it. Covers event coverage, attribution, retention, export and alerting: the properties that decide whether an investigation is possible at all. Kept deliberately small so it can run alongside a domain-specific set rather than competing with it for session time.
* **Risk types:** Information Security, Audit Readiness, Operational Risk
* **Risk domains:** Incident Response, Risk Governance
* **Typical use cases:** Establishing whether an application supports a forensic investigation; Log retention and export verification for an in-scope application; Evidence for a monitoring control in an audited environment; Pre-incident readiness check on a critical SaaS tenant
* **Coverage:** 13 controls across 3 sections
## Application classes
| Template | Controls | Focus |
| - | -: | - |
| CRM Application Controls | 22 | Information Security, Data Privacy |
| HRIS & Payroll Application Controls | 18 | Data Privacy, Information Security |
| Financial Services Application Controls | 17 | Financial Controls, Regulatory Compliance |
A CRM holds the customer relationship: contacts, pipeline, contract terms, support history and whatever a salesperson attached to a record. It is usually the widest-reach application an organization runs and the one with the most integrations hanging off it. Written against the surfaces a Salesforce, HubSpot, Dynamics or Zoho admin console exposes.
* **Risk types:** Information Security, Data Privacy, Operational Risk
* **Risk domains:** Data Protection, Identity & Access Management
* **Typical use cases:** Continuous monitoring of the organization's primary CRM; Detecting customer data leaving through a CRM integration; Sharing-model verification after a CRM administrator change; Pipeline and contract data exposure review
* **Coverage:** 22 controls across 4 sections
An HRIS holds the most sensitive employee data an organization has (compensation, bank details, national identifiers, performance and health-related absence), and it is the system that drives access everywhere else. These controls read the access model, the identifier fields, the payroll change trail and the downstream provisioning that depends on it.
* **Risk types:** Data Privacy, Information Security, Financial Controls
* **Risk domains:** Data Protection, Identity & Access Management, Financial Reporting
* **Typical use cases:** Continuous monitoring of the system of record for employee data; Payroll change control evidence; Verifying HR-driven provisioning still reaches downstream applications; Employee personal-data exposure review
* **Coverage:** 18 controls across 4 sections
Controls for applications operating inside a regulated financial institution, where the supervisory expectation is continuous rather than annual. Covers segregation of duties, records retention under books-and-records rules, communications capture, change control and the operational resilience evidence supervisors increasingly ask to see for a critical third party.
* **Risk types:** Financial Controls, Regulatory Compliance, Operational Risk
* **Risk domains:** Banking & Finance, Financial Reporting, Operational Continuity
* **Typical use cases:** Continuous control evidence for a regulated financial institution; Books-and-records retention verification on a communications tool; Segregation-of-duties monitoring in a financial application; Critical third-party resilience evidence for a supervisor
* **Coverage:** 17 controls across 4 sections
## Framework-derived
Use this set when a security reviewer wants a framework they recognize rather than Coverbase's own baselines.
| Template | Controls | Focus |
| - | -: | - |
| CIS Controls v8.1 SaaS Baseline NEW | 30 | Information Security, Operational Risk |
The CIS Critical Security Controls v8.1, read from a SaaS application's live admin console. Thirty controls across account management, access control, secure configuration, data protection, audit log management, alerting and service provider management, each derived from one CIS safeguard. A control decides only what the tenant's admin console can show for its safeguard: the enforcement state, the threshold, the list. The safeguard's process half, a documented policy or a review cadence, is not something a console shows and is not claimed. The instructions name each surface the way several vendors label it, so the same set runs against Salesforce, Box, Workday or a niche tool.
Each control cites its CIS safeguard and the NIST SP 800-53 Rev. 5 controls that CIS's own v8.1 mapping ties that safeguard to. The references appear on the evaluation, the finding and the control editor, and carry over when you fork the set.
**Official source:** [CIS Critical Security Controls v8.1](https://www.cisecurity.org/controls/v8-1)
* **Risk types:** Information Security, Operational Risk
* **Risk domains:** Identity & Access Management, Data Protection
* **Typical use cases:** Demonstrating SaaS posture against a framework a security reviewer recognizes; Continuous verification of CIS Controls v8.1 safeguards on business applications; Detecting posture drift against a CIS-anchored baseline between runs; Evidence for a NIST or CIS compliance report from live tenant configuration
* **Sections:** Access Control Management (CIS Control 6), Account Management (CIS Control 5), Secure Configuration (CIS Control 4), Data Protection (CIS Control 3), Audit Log Management and Alerting (CIS Controls 8 and 17), Connected Applications (CIS Controls 15 and 2)
* **Coverage:** 30 controls across 6 sections
# API conventions
Source: https://docs.coverbase.com/conventions
Authentication, base URLs, IDs, timestamps, idempotency, pagination, and the error envelope shared by all endpoints.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
This page covers behavior shared by every public API endpoint. Read it once; the per-resource pages assume it.
## Base URLs
| Environment | Base URL |
| - | - |
| Production | `https://api.coverbase.app` |
All requests are JSON over HTTPS. Every path is versioned under `/v1`.
## Authentication
Every request must send a bearer token:
```text theme={null}
Authorization: Bearer ak_...
```
Two credential types are accepted:
* **Service-account API key** (`ak_...`): the primary credential for integrations. An admin in your organization mints it on the dashboard's **API keys** page (Clerk-backed). It is scoped to exactly one organization; everything the key reads or writes is implicitly scoped to that org. It authenticates as a service account. By default a key carries no scopes and can only call ordinary `/v1/*` routes; an admin can additionally grant it elevated [scopes](#api-key-scopes).
* **OAuth 2.0 access token** (`cbat_...`): a short-lived token an [OAuth client](/api-reference/oauth) obtains with the client credentials grant. It authenticates as the same service account as an `ak_*` key, carries the client's elevated scopes, and is accepted wherever an `ak_*` key is. Available to organizations in the third-party lifecycle beta.
* **Logged-in user JWT**: the dashboard session token, useful for first-party scripts running as a specific user. A few endpoint families in this reference accept only this credential and reject `ak_` keys: the [Bill of Materials API](/api-reference/bill-of-materials), the [Zero Touch Assessments API](/api-reference/zero-touch-assessments), the org update and `whoami` endpoints below, and the `POST /v1//query` routes in the [field reference](/fields/overview). The [Import API](/import) is the reverse: it accepts only `ak_` keys.
Admins can list, create, rotate, and revoke `ak_*` keys self-service via the [API Keys API](/api-reference/api-keys). No support ticket required.
### API key scopes
Most `ak_*` keys carry **no scopes**: they authenticate ordinary `/v1/*` calls but cannot reach the admin surfaces. An admin can mint a long-lived key carrying one or more elevated scopes for headless or middleware use:
| Scope | Grants |
| - | - |
| `keys:manage` | List, create, rotate, and revoke `ak_*` keys via the [API Keys API](/api-reference/api-keys). |
| `audit:read` | Read the org system audit log (`GET /v1/system_audit_log` and `GET /v1/system_audit_log/metadata`). |
| `banking:read` | Read **full** supplier bank account and tax identifiers. Without it, every response returns the masked last four characters (`****4567`) and nothing more. |
| `review:sensitive_changes` | Write bank details straight to active without passing through the review queue. It does not let a key approve or reject a change someone else queued; a reviewer decides those in the dashboard. |
`banking:read` and `review:sensitive_changes` are the two scopes worth pausing on. The first lets a key read account numbers in full; the second lets a key bypass the human review that a bank-detail change would otherwise wait for. Both are deliberate, admin-minted and revocable, and neither is granted by default. Leave them off unless a specific integration genuinely needs them, and see [Data protection](/security/data-protection#role-based-masking) for what is masked without them.
The key-management and audit-log endpoints accept **either** a dashboard JWT **or** an `ak_*` key carrying the required scope, so you can run them headlessly without a short-lived session token. Key management requires the org `admin` role; audit-log reads accept member, siloed member, and admin sessions.
Scopes can only be granted from an **admin dashboard session (JWT)**. A scoped key cannot grant scopes, not to itself and not to another key, so a leaked integration key can never escalate its own access. A request that passes `scopes` without an admin JWT is rejected with `403 scope_grant_forbidden`; a call to a scoped endpoint with a key that lacks the required scope returns `403 insufficient_scope`.
There is no unauthenticated surface. A request with no `Authorization` header returns `403 "Not authenticated"`. An invalid/expired/revoked key returns `401 "Invalid or expired API key."`. A credential whose role is not allowed on the endpoint returns `401 "Unauthorized role."`.
### Public API audit log
Every call made with an `ak_*` key to a public API resource endpoint (vendors, documents, users, assessments, findings, obligations, radar, reassessments, custom fields, workflows, webhooks, and the Import API) is recorded in the org's activity log as `type=external_api_call` with `target_type=external_api_request`. Each record captures:
* the HTTP method, request path, and matched route template
* the response status code and duration in milliseconds
* the names of query parameters used (values are not recorded)
* the `ak_*` key ID and human-readable name that authenticated the request
* the client IP and a per-request correlation ID
Request and response bodies are not stored, with one exception: a call to a custom [Import API](/import) report stores both bodies, redacted and capped at 1 MB, and shows them on that report's **Request history** tab. The records surface in the dashboard under **Configuration → Audit Logs** (in the **Integrations** group) and through `GET /v1/system_audit_log` (and `GET /v1/system_audit_log/metadata`). Both read endpoints accept **either** a dashboard session JWT (member, siloed member, or admin) **or** an `ak_*` key that carries the [`audit:read` scope](#api-key-scopes).
Requests that fail authentication before the `ak_*` key resolves (for example, an unknown or revoked key returning `401`) are not stored in the activity log; they appear in Coverbase's structured request logs only and can be retrieved via support if needed for incident response.
### Test your credentials
`GET /v1/utils/authtest` returns `200` and `{"msg": "Auth successful"}` for any valid token.
```bash cURL theme={null}
curl -H "Authorization: Bearer ak_live_xxx" \
https://api.coverbase.app/v1/utils/authtest
```
## API IP allowlist
An organization can optionally restrict **all public API (`ak_...` key) requests** to a set of IPv4/IPv6 CIDRs. This is an org-level control configured by an admin.
* **Default is unrestricted.** An empty allowlist (`[]`, the default) imposes no restriction.
* **When configured**, a request whose client IP is outside *every* configured CIDR is rejected with `403`:
```json theme={null}
{ "detail": { "code": "ip_not_allowed", "message": "This request originates from an IP address that is not in your organization's API allowlist." } }
```
* **Fail-closed.** If an allowlist is configured but the client IP cannot be determined, the request is denied.
* **Scope.** The allowlist applies to the public API resource endpoints: vendors (including bank accounts, sites, and other supplier profile data), documents, users, assessments, findings, obligations, radar, reassessments, custom fields, workflows, and webhooks. It does **not** apply to the API Keys, Intake, Import, and Export endpoints, and it does not affect dashboard sign-in.
* **Client IP source.** The connecting IP is the value the Coverbase load balancer appends to `X-Forwarded-For`. Clients cannot spoof it by sending their own `X-Forwarded-For` header.
### Configure the allowlist
Set the allowlist from the dashboard (**Configuration → Coverbase API → API IP allowlist**) or via the org update API. The org update endpoint takes an admin's dashboard session token; an `ak_` key can read the org object but cannot change it. Your organization ID is the `id` field on the org object (also visible in the dashboard).
A list of CIDR strings (IPv4 or IPv6). Each entry is validated server-side; an invalid CIDR rejects the whole request with `422`. An empty list clears the allowlist (unrestricted).
```bash Set the allowlist theme={null}
curl -X POST "https://api.coverbase.app/v1/org/cborg_xxx" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{ "api_ip_allowlist": ["203.0.113.0/24", "198.51.100.7/32"] }'
```
```bash Read it back theme={null}
curl "https://api.coverbase.app/v1/org/cborg_xxx" \
-H "Authorization: Bearer ak_live_xxx" | jq .api_ip_allowlist
```
```bash Clear it (unrestricted again) theme={null}
curl -X POST "https://api.coverbase.app/v1/org/cborg_xxx" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{ "api_ip_allowlist": [] }'
```
The org object (`GET`/`POST /v1/org/{id}`) now includes `api_ip_allowlist` (a string array; `[]` when unrestricted). An invalid CIDR returns `422` with a free-form error body (not the coded envelope):
```json theme={null}
{ "detail": { "error": "Invalid CIDR in api_ip_allowlist", "value": "not-a-cidr" } }
```
Add the egress IPs of your integration **before** enabling the allowlist, and keep a dashboard admin path available: a too-narrow allowlist locks every API client out until it is widened or cleared from the dashboard.
### Find your current IP
`GET /v1/whoami/ip`
A convenience endpoint that returns the caller's source IP as the API sees it: the load-balancer-appended, unspoofable value. It takes a dashboard session token; `ak_` keys are rejected with `401 Unauthorized role.` This is the **same value** evaluated by the org `api_ip_allowlist` check, so use it to confirm which IP to allowlist (it backs the dashboard editor's "Add my current IP" helper).
```bash cURL theme={null}
curl -sS "https://api.coverbase.app/v1/whoami/ip" \
-H "Authorization: Bearer " # → {"client_ip":"203.0.113.42"}
```
The caller's source IP. `null` if the IP cannot be determined: the same condition under which a configured allowlist fails closed.
## IDs
Resource IDs are opaque, prefixed strings of the form `_<32 hex characters>` (for example, `cbvndr_e448ba62882143f3ba0c140bb2e30162`). Treat them as opaque: never parse or construct them.
| Prefix | Resource |
| - | - |
| `cbvndr_` | Vendor |
| `cbsvc_` | Service (child of a vendor) |
| `cbuser_` | User |
| `cbqsrw_` | Assessment |
| `cbtask_` | Finding |
| `cboblg_` | Obligation |
| `cbwr_` | Workflow run |
| `cbwd_` | Workflow definition |
| `cbwh_` | Webhook subscription |
| `cbctst_` | Control set |
| `cbst_` | Status |
| `cbtag_` | Tag |
| `cbsclvl_` | Scale level (inherent/residual risk level) |
| `cbvdoc_` | Vendor document |
| `cbbom_` | Bill of materials |
| `cbbomc_` | Bill of materials component |
| `cbevt_` | Webhook delivery event |
| `cbwhd_` | Webhook delivery (attempt record) |
| `cborg_` | Organization |
| `cbegm_` | Engagement record |
| `cbcontract_` | Contract record |
| `cbci_` | OAuth client ID |
Findings are internally called "tasks", so finding IDs use the `cbtask_` prefix. This is expected. A `cbtask_...` value **is** a finding ID.
## Timestamps
Every timestamp is a **Unix epoch value in seconds** (integer), not milliseconds, not ISO-8601. This applies to `created_at`, `updated_at`, `initiated_at`, `started_at`, `completed_at`, `due_date`, `occurred_at`, and `attempted_at`.
## Idempotency
State-changing `POST`s that support safe retries accept an optional `Idempotency-Key` request header.
| Endpoint | Honors `Idempotency-Key` |
| - | - |
| `POST /v1/users` | Yes |
| `POST /v1/vendors` | Yes |
| `POST /v1/assessments` | Yes |
| `POST /v1/documents` | Yes |
| `POST /v1/intake/api/documents` | Yes |
| `POST /v1/workflows/{workflow_name}/run` | Yes |
| `POST /v1/workflows/{workflow_name}/schedule` | Yes |
| `POST /v1/vendors/{vendor_id}/services` | **No** (header ignored) |
| `POST /v1/findings`, `POST /v1/obligations` | **No** (header ignored) |
| `POST /v1/webhooks` and other webhook writes | **No** (header ignored) |
| `PATCH` endpoints | **No** |
Behavior on supported endpoints: keys are scoped to **(org, endpoint, key)** and expire **24 hours** after first use. The endpoint is the route template, so on the workflow endpoints one key covers every `workflow_name`: reusing a key for a different workflow within 24 hours replays the first response. A replay within the window returns the **original response body verbatim** (same status) and creates nothing new. A replay is never rejected; there is no conflict error. Sending the header to an endpoint that does not support it is harmless but has no effect.
Use a stable identifier from the source system (a procurement request ID, a ticket number) as the idempotency key so source-side retries deduplicate naturally.
## Pagination
List endpoints (`GET /v1/vendors`, `GET /v1/users`, `GET /v1/portals`, `GET /v1/findings`, `GET /v1/obligations`, `GET /v1/contract-records`, `GET /v1/engagement-records`, and the Radar lists) use `limit`/`offset` query parameters:
| Param | Default | Range |
| - | - | - |
| `limit` | `50` | `1`-`200` |
| `offset` | `0` | `≥ 0` |
List responses wrap results as `{ "items": [...], "total": , "limit": , "offset": }`. `total` is the full filtered count (ignoring `limit`/`offset`); page until `offset + len(items) >= total`.
A few lists differ. `GET /v1/documents` and `GET /v1/webhooks/{webhook_id}/deliveries` return the page under `data` instead of `items`. `GET /v1/workflows/runs` also uses `data`, with `limit` defaulting to `100` and allowed up to `500`. `GET /v1/reassessments` returns every match in one page.
## Errors
Application errors use FastAPI's `detail` envelope. Most endpoints return a coded object:
```json theme={null}
{ "detail": { "code": "vendor_not_found", "message": "Vendor not found." }, "request_id": "41ff4305-740d-4181-bed9-1fbe21bd69ab" }
```
Every error body carries a `request_id`, also sent as the `x-coverbase-request-id` response header. Quote it when you contact support.
Some endpoints do not use the coded object. `POST /v1/assessments` creation failures use a free-form `error` key:
```json theme={null}
{ "detail": { "error": "..." } }
```
`POST /v1/custom-fields/values`, the Bill of Materials, Intake, Import, and Export endpoints, and authentication failures return `detail` as a plain string.
### Validation errors
Bodies/params that fail schema validation return `422` with FastAPI's standard array:
```json theme={null}
{
"detail": [
{ "loc": ["body", "vendor_id"], "msg": "Field required", "type": "missing" }
]
}
```
### Common status codes
| Status | Meaning |
| - | - |
| `400` | Rejected by a business rule (bad reference ID, weak secret, non-HTTPS URL). |
| `401` | Invalid, expired, or revoked credential, or a role not allowed on the endpoint. |
| `403` | No `Authorization` header (`Not authenticated`), or authenticated but not authorized: the key lacks a required scope (`insufficient_scope`), a non-admin tried to grant scopes (`scope_grant_forbidden`), or the client IP is outside the org allowlist (`ip_not_allowed`). |
| `404` | Resource not found or not in the API key's org. |
| `409` | Conflict: for example, `user_exists`, or running a disabled workflow (`workflow_disabled`). |
| `422` | Request body/query failed schema validation. |
| `502` | An upstream provider failed (for example, `clerk_upstream_error` on the API Keys API); safe to retry. |
# Export API Reference
Source: https://docs.coverbase.com/export
Endpoint reference for retrieving report data via the Coverbase Export API.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
## Export Report
`GET /v1/export/{slug}`
Retrieves the data for the specified report. Authenticate with an `ak_` API key (see [Authentication](/quickstart)).
### Path parameters
The report's slug, as set on the report in the dashboard. It is also returned as `slug`.
### Query parameters
The maximum number of JSON objects to return in the `data` array.
The number of records to skip before starting to return data.
Case-insensitive substring filter on the supplier/vendor name. Applies to
vendor-based reports (for example, the all-suppliers report); ignored for
other base objects. `total_count` reflects the filtered result.
For `radar_run` reports only: include runs that started at or after this Unix timestamp (seconds). Ignored for other base objects.
For `radar_run` reports only: include runs that started before this Unix timestamp (seconds). Ignored for other base objects.
A negative `limit` or `offset` returns `400`. An unknown slug returns `404` with `{"detail": "Export report not found"}`.
### Example request
```bash cURL theme={null}
curl -X GET "https://api.coverbase.app/v1/export/vendor-custom-report?limit=10&offset=20" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json"
```
```python Python theme={null}
import os
import requests
API_KEY = os.getenv("COVERBASE_API_KEY", "")
BASE_URL = "https://api.coverbase.app"
slug = "vendor-custom-report"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
resp = requests.get(
f"{BASE_URL}/v1/export/{slug}?limit=10&offset=20",
headers=headers,
timeout=30,
)
resp.raise_for_status()
report = resp.json()
print(f"Report: {report['report_name']} ({report['base_object']})")
print(f"Returned {len(report['data'])} of {report['total_count']} records")
```
### Example response
```json theme={null}
{
"id": "cbexprt_a13361e835664c26bb0551a860258f6d",
"slug": "vendor-custom-report",
"report_name": "Vendor Report",
"base_object": "vendor",
"mapping": {
"id": "Id",
"name": "Name",
"status": "Status",
"website": "Website",
"products": "Products",
"created_at": "Created At",
"description": "Description",
"hq_location": "Hq Location"
},
"data": [
{
"Id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"Name": "Acme Corporation",
"Status": "Active",
"Website": "acmecorp.example",
"Products": [],
"Created At": 1731132522,
"Description": "Acme Corporation provides workforce analytics software for mid-market employers.",
"Hq Location": "San Francisco, CA"
}
],
"limit": 10,
"offset": 20,
"total_count": 157
}
```
### Response fields
Unique Coverbase export report ID.
Unique string used in the API endpoint URL.
Display name for the report.
The object each record in `data` represents (for example, `vendor` or `assessment`).
Mapping between Coverbase field names and the field names exported in the JSON objects.
Array of JSON objects. Each object represents one `base_object` and contains field names specified by the values in the `mapping` object.
The maximum length of the `data` array.
The number of records skipped before the system began returning records.
Total number of records the report matches, before `limit` and `offset`.
## Download a report as a file
`GET /v1/export/{slug}/download`
Returns the same data as a CSV or Excel file instead of JSON. The columns are the report's mapped field names, and the file is named after the slug (for example `vendor-custom-report.csv`).
`csv` or `xlsx`.
The `limit`, `offset`, `supplier_name`, `start_ts`, and `end_ts` parameters work as above. One request returns at most 100,000 rows; page with `limit` and `offset` for larger reports.
```bash cURL theme={null}
curl -L -o vendor-custom-report.xlsx \
"https://api.coverbase.app/v1/export/vendor-custom-report/download?format=xlsx" \
-H "Authorization: Bearer "
```
Need help? Email [support@coverbase.ai](mailto:support@coverbase.ai).
# Export API Concepts
Source: https://docs.coverbase.com/export-api-concepts
Pull vendor, assessment, control, and evaluation data out of Coverbase via configurable report endpoints.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Export API is the backbone for automating your third-party risk management program. It enables secure, direct retrieval of vendor profiles, risk assessments, control evaluations, and related compliance data.
## What you can do
Swap manual spreadsheet tracking for live system data pulled directly from Coverbase.
Pipe vendor and assessment information into internal compliance dashboards.
Generate regulatory reports by pulling structured control evaluations on a schedule.
Drive remediation in ServiceNow, Jira, or other internal tools when evaluations surface issues.
The API uses a RESTful design with a predictable URL structure and communicates entirely in JSON. All interactions are authenticated and encrypted.
## Setup
The Export API requires you to first create a report in the [dashboard](https://dashboard.coverbase.app/api): open **Configuration → Coverbase API**, stay on the **Export API** tab, and click **New Export Report**. A report defines the URL of the endpoint (its slug), the data it returns, and the field labels it uses on the way out.
To configure the report, you first pick a **base object** under **Report contains an array of**. When you call the API endpoint, it returns an array of JSON objects, each representing one instance of that base object. Call it with an `ak_` API key; see [Authentication](/quickstart).
## Base objects
The following base objects are currently supported.
### Vendor
Vendor records include metadata such as name, website, ownership, risk level, and tags.
**Example:** A supplier record for "Acme Corp, Payments API" might differ from "Acme Corp, Cloud Hosting" if both are used by different teams.
### Assessment
An assessment is an analysis of a vendor's documents, questionnaires, and contextual data against one or more control sets. Assessments are automatically populated, reviewed, and scored by Coverbase's AI engine.
**Example:** Reviewing Acme Corp's SOC 2 and CAIQ to determine whether they meet your encryption and access control expectations.
### Evaluation
Assessments produce evaluations. Each evaluation is the result of analyzing a single control. There are as many evaluations as there are controls being assessed. Evaluations with weaknesses are considered issues. Each one carries context, evidence citations, and optional recommended mitigations.
**Example:** "Encryption control unmet, no evidence of data-at-rest encryption found in SOC 2."
### Control
An atomic requirement used to evaluate a supplier's security, legal, or operational posture. Each control has an expectation, guidance, weight, and supporting evidence references.
**Example:** "Vendor must encrypt customer data at rest with AES-256 or stronger."
### Control Set
A collection of controls representing a full evaluation standard. Control sets may include sections (such as "Data Security" or "Business Continuity") and are versioned for auditability.
**Example:** A custom control set derived from your internal security questionnaire.
### Other base objects
A report can also return any of these objects. The label is what the dashboard shows; `base_object` is the value in the API response.
| Label | `base_object` |
| - | - |
| Activity Logs | `activity_log` |
| Contracts | `contract` |
| Findings | `finding` |
| Finding Commitments | `finding_commitment` |
| Obligation Commitments | `obligation_commitment` |
| Questionnaire Responses | `questionnaire_response` |
| Services | `service` |
| Status Transitions | `status_transition` |
| Users | `user` |
| SOC 1 Type 1 Auditor Reports | `soc1_type1_auditor_report` |
| SOC 1 Type 2 Auditor Reports | `soc1_type2_auditor_report` |
| SOC 2 Type 2 Auditor Reports | `soc2_type2_auditor_report` |
| ISO 27001 Certificates | `iso_27001_certificate` |
| PCI Attestations of Compliance | `pci_attestation_of_compliance` |
| Certificates of Insurance | `certificate_of_insurance_acord_25` |
| Radar Signals | `radar_signal` |
| Radar Runs | `radar_run` |
The commitment objects are grouped under **Commitments** in the picker and the document types under **Document Types**. **Radar Signals** and **Radar Runs** appear only when Supplier Radar is enabled for your organization.
# Field catalog
Source: https://docs.coverbase.com/fields/catalog
Every filterable, sortable, and queryable field in Coverbase, by module.
This catalog lists every published field across the core modules, grouped by
where the field appears. See [Field reference](/fields/overview) for how to read
the columns and what the operators mean.
Labels use the Coverbase default terminology. If your workspace has renamed a
term, the label differs but the filter path does not.
## Vendors
The **Vendors** list and every vendor record header.
**48 fields**, queryable at `POST /v1/vendor/query`, available in saved views, usable as the `vendor` target in workflow conditions, extendable with custom fields.
Default sort: `name` asc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Created Date | Dates | `created_at` | Date | - | after, before, on or after, on or before, between | Yes |
| Next Assessment Date | Dates | `next_assessment_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Last Assessed | Dates | `last_assessed_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | Yes |
| Document Types | Documents | `documents.document_type` | Choice | Document types in your workspace | any of, none of, all of, not all of | No |
| Document Count | Documents | `documents.count` | Number | - | at least, at most, is, is not | Yes |
| Uploaded Date | Documents | `documents.created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Contract Auto Renewal | Contracts | `contracts.auto_renew` | Choice | `none`, `automatic`, `manual` | is, is not, any of, none of | No |
| Contract Effective Date | Contracts | `contracts.effective_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Contract Expiration Date | Contracts | `contracts.expiration_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Contract Term Start Date | Contracts | `contracts.term_start_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Contract Renewal Date | Contracts | `contracts.renewal_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Contract Notice Due Date | Contracts | `contracts.notice_due_to_vendor_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Contract Action Date | Contracts | `contracts.action_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Contract Audit Date | Contracts | `contracts.audit_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Contract Created Date | Contracts | `contracts.created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Contract Updated Date | Contracts | `contracts.updated_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Contract Count | Contracts | `contracts.count` | Number | - | at least, at most, is, is not | No |
| Assessment Count | Assessments | `assessments.count` | Number | - | at least, at most, is, is not | Yes |
| Assessment Status | Assessments | `assessments.status_id` | Reference | Assessment statuses in your workspace | is, is not, any of, none of, empty, not empty | No |
| Assessment Outcome | Assessments | `assessments.approval_option_id` | Reference | Approval options in your workspace | is, is not, any of, none of, empty, not empty | No |
| Assessment Assignee | Assessments | `assessments.assignee_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Assessment Risk Type | Assessments | `assessments.risk_type` | Choice | `inherent_risk`, `residual_risk`, `untargeted` | is, is not, any of, none of | No |
| Assessment Portal State | Assessments | `assessments.portal_state` | Choice | `open`, `submitted`, `closed`, `overdue` | is, is not, any of, none of, empty, not empty | No |
| Assessment Inherent Risk | Assessments | `assessments.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Assessment Zero Touch | Assessments | `assessments.is_zero_touch` | Yes/No | - | is, is not | No |
| Assessment Has Open Issue | Assessments | `assessments.has_open_issue` | Yes/No | - | is, is not | No |
| Assessment Created Date | Assessments | `assessments.created_at` | Date | - | after, before, on or after, on or before, between | No |
| Assessment Completed Date | Assessments | `assessments.completed_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | No |
| Assessment Outcome | - | `last_assessment_outcome` | Reference | Approval options in your workspace | is, is not, any of, none of, empty, not empty | No |
| Inherent Risk Level | - | `inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | Yes |
| Inherent Risk Score | - | `raw_irq_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | Yes |
| Vendor Name | - | `name` | Text | - | is, is not, any of, none of, contains, does not contain | Yes |
| Relationship Owners | - | `relationship_owners` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | Yes |
| Residual Risk Level | - | `residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Residual Risk Score | - | `raw_residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Risk Analysts | - | `risk_analysts` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | Yes |
| Risk Domain Inherent Risk Level | - | `risk_domain_scores.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Risk Domain Inherent Risk Score | - | `risk_domain_scores.inherent_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Risk Domain Residual Risk Level | - | `risk_domain_scores.residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Risk Domain Residual Risk Score | - | `risk_domain_scores.residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Risk Domains | - | `risk_domain_scores.risk_domain_id` | Reference | Risk domains in your workspace | is, is not, any of, none of, empty, not empty | No |
| Status | - | `status_id` | Reference | Vendor statuses in your workspace | is, is not, any of, none of, empty, not empty | Yes |
| Archived | - | `is_archived` | Yes/No | - | is, is not | No |
| Tags | - | `tags` | Multi-reference | Tags in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor | - | `id` | Reference | Vendors in your workspace | is, is not, any of, none of | No |
| Watchers | - | `watchers` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | Yes |
| Website | - | `website` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | Yes |
| Tier | - | `tier` | Choice | `tier_1`, `tier_2`, `tier_3`, `tier_4` | is, is not, any of, none of, empty, not empty | No |
## Services
The **Services** view on the **Vendors** page, and service records.
**60 fields**, queryable at `POST /v1/service/query`, available in saved views, usable as the `service` target in workflow conditions, extendable with custom fields.
Default sort: `name` asc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Service Name | - | `name` | Text | - | is, is not, any of, none of, contains, does not contain | Yes |
| Contracts | Contracts | `contracts` | Multi-reference | - | any of, none of, all of, not all of, empty, not empty | No |
| Contract Count | Contracts | `contracts.count` | Number | - | at least, at most, is, is not | No |
| Next Assessment Date | Dates | `next_assessment_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Created Date | Dates | `created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Vendor | Vendor | `vendor_id` | Reference | Vendors in your workspace | is, is not, any of, none of, empty, not empty | Yes |
| Vendor Created Date | Vendor › Dates | `vendor.created_at` | Date | - | after, before, on or after, on or before, between | No |
| Vendor Document Types | Vendor › Documents | `vendor.documents.document_type` | Choice | Document types in your workspace | any of, none of, all of, not all of | No |
| Vendor Document Count | Vendor › Documents | `vendor.documents.count` | Number | - | at least, at most, is, is not | No |
| Vendor Next Assessment Date | Vendor › Dates | `vendor.next_assessment_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Vendor Last Assessed | Vendor › Dates | `vendor.last_assessed_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | No |
| Vendor Uploaded Date | Vendor › Documents | `vendor.documents.created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Vendor | - | `vendor.id` | Reference | Vendors in your workspace | is, is not, any of, none of | No |
| Vendor Assessment Count | Vendor › Assessments | `vendor.assessments.count` | Number | - | at least, at most, is, is not | No |
| Vendor Assessment Status | Vendor › Assessments | `vendor.assessments.status_id` | Reference | Assessment statuses in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Assessment Outcome | Vendor › Assessments | `vendor.assessments.approval_option_id` | Reference | Approval options in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Assessment Assignee | Vendor › Assessments | `vendor.assessments.assignee_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Assessment Risk Type | Vendor › Assessments | `vendor.assessments.risk_type` | Choice | `inherent_risk`, `residual_risk`, `untargeted` | is, is not, any of, none of | No |
| Vendor Assessment Portal State | Vendor › Assessments | `vendor.assessments.portal_state` | Choice | `open`, `submitted`, `closed`, `overdue` | is, is not, any of, none of, empty, not empty | No |
| Vendor Assessment Inherent Risk | Vendor › Assessments | `vendor.assessments.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Assessment Zero Touch | Vendor › Assessments | `vendor.assessments.is_zero_touch` | Yes/No | - | is, is not | No |
| Vendor Assessment Has Open Issue | Vendor › Assessments | `vendor.assessments.has_open_issue` | Yes/No | - | is, is not | No |
| Vendor Assessment Created Date | Vendor › Assessments | `vendor.assessments.created_at` | Date | - | after, before, on or after, on or before, between | No |
| Vendor Assessment Completed Date | Vendor › Assessments | `vendor.assessments.completed_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | No |
| Vendor Assessment Outcome | Vendor | `vendor.last_assessment_outcome` | Reference | Approval options in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Inherent Risk Level | Vendor | `vendor.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Inherent Risk Score | Vendor | `vendor.raw_irq_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Name | Vendor | `vendor.name` | Text | - | is, is not, any of, none of, contains, does not contain | Yes |
| Vendor Relationship Owners | Vendor | `vendor.relationship_owners` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Residual Risk Level | Vendor | `vendor.residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Residual Risk Score | Vendor | `vendor.raw_residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Risk Analysts | Vendor | `vendor.risk_analysts` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Risk Domain Inherent Risk Level | Vendor | `vendor.risk_domain_scores.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Risk Domain Inherent Risk Score | Vendor | `vendor.risk_domain_scores.inherent_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Risk Domain Residual Risk Level | Vendor | `vendor.risk_domain_scores.residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Risk Domain Residual Risk Score | Vendor | `vendor.risk_domain_scores.residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Risk Domains | Vendor | `vendor.risk_domain_scores.risk_domain_id` | Reference | Risk domains in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Status | Vendor | `vendor.status_id` | Reference | Vendor statuses in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Tags | Vendor | `vendor.tags` | Multi-reference | Tags in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Watchers | Vendor | `vendor.watchers` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Website | Vendor | `vendor.website` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| Vendor Archived | Vendor | `vendor.is_archived` | Yes/No | - | is, is not | No |
| Vendor Tier | Vendor | `vendor.tier` | Choice | `tier_1`, `tier_2`, `tier_3`, `tier_4` | is, is not, any of, none of, empty, not empty | No |
| Description | - | `description` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| Document Types | Documents | `vendor_documents.document_type` | Choice | Document types in your workspace | any of, none of, all of, not all of | No |
| Uploaded Date | Documents | `vendor_documents.created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Document Count | Documents | `vendor_documents.count` | Number | - | at least, at most, is, is not | No |
| Status | - | `status_id` | Reference | Service statuses in your workspace | is, is not, any of, none of, empty, not empty | No |
| Relationship Owners | - | `relationship_owners` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Watchers | - | `watchers` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Inherent Risk Score | - | `raw_irq_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Inherent Risk Level | - | `inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | Yes |
| Residual Risk Score | - | `raw_residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Residual Risk Level | - | `residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Risk Domain Inherent Risk Level | - | `risk_domain_scores.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Risk Domain Inherent Risk Score | - | `risk_domain_scores.inherent_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Risk Domain Residual Risk Level | - | `risk_domain_scores.residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Risk Domain Residual Risk Score | - | `risk_domain_scores.residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Risk Domains | - | `risk_domain_scores.risk_domain_id` | Reference | Risk domains in your workspace | is, is not, any of, none of, empty, not empty | No |
| Service | - | `id` | Reference | Services in your workspace | is, is not, any of, none of | No |
## Engagements
The **Engagements** tab on a vendor, and engagement records.
**25 fields**, queryable at `POST /v1/engagement/query`, available in saved views, usable as the `engagement` target in workflow conditions.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Engagement Name | - | `name` | Text | - | is, is not, any of, none of, contains, does not contain | Yes |
| Contracts | Contracts | `contracts` | Multi-reference | - | any of, none of, all of, not all of, empty, not empty | No |
| Contract Count | Contracts | `contracts.count` | Number | - | at least, at most, is, is not | No |
| Start Date | Dates | `start_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| End Date | Dates | `end_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Start Date Mode | Dates | `start_date_mode` | Choice | `MANUAL`, `COMPUTED` | is, is not, any of, none of | No |
| End Date Mode | Dates | `end_date_mode` | Choice | `MANUAL`, `COMPUTED` | is, is not, any of, none of | No |
| Created Date | Dates | `created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Updated Date | Dates | `updated_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Services | Services | `services` | Multi-reference | - | any of, none of, all of, not all of, empty, not empty | No |
| Service Count | Services | `services.count` | Number | - | at least, at most, is, is not | No |
| Vendor | Vendor | `vendor_id` | Reference | Vendors in your workspace | is, is not, any of, none of, empty, not empty | Yes |
| Description | - | `description` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| Status | - | `status_id` | Reference | - | is, is not, any of, none of, empty, not empty | No |
| Created By | - | `created_by_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Inherent Risk Score | - | `raw_irq_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Inherent Risk Level | - | `inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Residual Risk Score | - | `raw_residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Residual Risk Level | - | `residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Risk Domain Inherent Risk Level | - | `risk_domain_scores.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Risk Domain Inherent Risk Score | - | `risk_domain_scores.inherent_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Risk Domain Residual Risk Level | - | `risk_domain_scores.residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Risk Domain Residual Risk Score | - | `risk_domain_scores.residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Risk Domains | - | `risk_domain_scores.risk_domain_id` | Reference | Risk domains in your workspace | is, is not, any of, none of, empty, not empty | No |
| Engagement | - | `id` | Reference | Engagements in your workspace | is, is not, any of, none of | No |
## Contracts
The **Contracts** list and contract records, including Contract Guardian.
**64 fields**, queryable at `POST /v1/contract/query`, available in saved views, usable as the `contract` target in workflow conditions, extendable with custom fields.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Name | - | `name` | Text | - | is, is not, any of, none of, contains, does not contain | Yes |
| Effective Date | Dates | `effective_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Expiration Date | Dates | `expiration_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Term Start | Dates | `term_start_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Renewal Date | Dates | `renewal_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Notice Due Date | Dates | `notice_due_to_vendor_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Action Date | Dates | `action_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Audit Date | Dates | `audit_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Created Date | Dates | `created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Updated Date | Dates | `updated_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Review Status | Reviews | `reviews.status_id` | Reference | Review statuses in your workspace | is, all are, is not, any of, none of, empty, not empty | No |
| Reviewer | Reviews | `reviews.assignee_ref` | Reference | Users and groups in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor | Vendor | `vendor_id` | Reference | Vendors in your workspace | is, is not, any of, none of | No |
| Vendor Created Date | Vendor › Dates | `vendor.created_at` | Date | - | after, before, on or after, on or before, between | No |
| Vendor Document Types | Vendor › Documents | `vendor.documents.document_type` | Choice | Document types in your workspace | any of, none of, all of, not all of | No |
| Vendor Document Count | Vendor › Documents | `vendor.documents.count` | Number | - | at least, at most, is, is not | No |
| Vendor Next Assessment Date | Vendor › Dates | `vendor.next_assessment_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Vendor Last Assessed | Vendor › Dates | `vendor.last_assessed_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | No |
| Vendor Uploaded Date | Vendor › Documents | `vendor.documents.created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Vendor Assessment Count | Vendor › Assessments | `vendor.assessments.count` | Number | - | at least, at most, is, is not | No |
| Vendor Assessment Outcome | Vendor | `vendor.last_assessment_outcome` | Reference | Approval options in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Inherent Risk Level | Vendor | `vendor.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Inherent Risk Score | Vendor | `vendor.raw_irq_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Relationship Owners | Vendor | `vendor.relationship_owners` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Residual Risk Level | Vendor | `vendor.residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Residual Risk Score | Vendor | `vendor.raw_residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Risk Analysts | Vendor | `vendor.risk_analysts` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Risk Domain Inherent Risk Level | Vendor | `vendor.risk_domain_scores.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Risk Domain Inherent Risk Score | Vendor | `vendor.risk_domain_scores.inherent_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Risk Domain Residual Risk Level | Vendor | `vendor.risk_domain_scores.residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Risk Domain Residual Risk Score | Vendor | `vendor.risk_domain_scores.residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Risk Domains | Vendor | `vendor.risk_domain_scores.risk_domain_id` | Reference | Risk domains in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Status | Vendor | `vendor.status_id` | Reference | Vendor statuses in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Tags | Vendor | `vendor.tags` | Multi-reference | Tags in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Watchers | Vendor | `vendor.watchers` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Website | Vendor | `vendor.website` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| Vendor Archived | Vendor | `vendor.is_archived` | Yes/No | - | is, is not | No |
| Vendor Tier | Vendor | `vendor.tier` | Choice | `tier_1`, `tier_2`, `tier_3`, `tier_4` | is, is not, any of, none of, empty, not empty | No |
| Description | - | `description` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| Document Types | Documents | `documents.document_type` | Choice | Document types in your workspace | any of, none of, all of, not all of | No |
| Uploaded Date | Documents | `documents.created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Document Count | Documents | `documents.count` | Number | - | at least, at most, is, is not | Yes |
| Contract Value | - | `contract_value_amount` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | Yes |
| Status | - | `status_id` | Reference | Contract statuses in your workspace | is, is not, any of, none of, empty, not empty | Yes |
| Auto-renews | - | `auto_renew` | Choice | `none`, `automatic`, `manual` | is, is not, any of, none of | No |
| Renewal Term | - | `contract_renewal_duration` | Structured | - | empty, not empty | No |
| Renewal Decision | - | `renewal_decision` | Choice | `undecided`, `renew`, `terminate`, `under_review` | is, is not, any of, none of | No |
| Renewals Applied | - | `renewal_count` | Number | - | is, is not, greater than, at least, less than, at most, between | Yes |
| Held For Intake Review | - | `intake_hold` | Yes/No | - | is, is not | No |
| Services | - | `services` | Multi-reference | - | any of, none of, all of, not all of, empty, not empty | No |
| Owners | - | `owners` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Watchers | - | `watchers` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Clause needs a decision | - | `clause_review_runs.matches.needs_decision` | Yes/No | - | is, is not | No |
| Commercially Active | - | `status` | Choice | `active`, `expired` | is, is not, any of, none of | No |
| Workflow | - | `workflow_state` | Choice | `draft`, `pending_approval`, `approved`, `sent_for_signature`, `executed`, `rejected`, `terminated` | is, is not, any of, none of | No |
| Contract Type | - | `contract_type` | Choice | `addendum`, `appendix`, `msa`, `sow`, `order_form`, `amendment`, `nda`, `dpa`, `baa`, `subscription_agreement`, `license_agreement`, `services_agreement`, `reseller_agreement`, `statement_of_services`, `letter_of_intent`, `renewal`, `other` | is, is not, any of, none of | No |
| Assembly | Components | `assembly_state` | Choice | `proposed`, `needs_review`, `confirmed`, `rejected` | is, is not, any of, none of | No |
| Relevance | Components | `relevance_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | Yes |
| Grouping Confidence | Components | `family_confidence` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Value Disagrees With Document | Components | `has_value_conflict` | Yes/No | - | is, is not | No |
| Component | Components | `component_slots.component_type` | Choice | Document types in your workspace | is, is not, any of, none of | No |
| Component Status | Components | `component_slots.gap_state` | Choice | `present`, `missing`, `expired`, `superseded_unclear`, `not_required` | is, is not, any of, none of | No |
| Component Needs Re-reading | Components | `component_slots.recheck_requested_at` | Date | - | empty, not empty, on or after, on or before | No |
| Component Count | Components | `component_slots.count` | Number | - | at least, at most, is, is not | No |
## Documents
The **Documents** list and the document tabs on vendors, assessments, and contracts.
**34 fields**, queryable at `POST /v1/vendor_document/query`, available in saved views, usable as the `vendor_document` target in workflow conditions.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Vendor Created Date | Vendor › Dates | `vendor.created_at` | Date | - | after, before, on or after, on or before, between | No |
| Vendor Document Types | Vendor › Documents | `vendor.documents.document_type` | Choice | Document types in your workspace | any of, none of, all of, not all of | No |
| Vendor Document Count | Vendor › Documents | `vendor.documents.count` | Number | - | at least, at most, is, is not | No |
| Vendor Next Assessment Date | Vendor › Dates | `vendor.next_assessment_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Vendor Last Assessed | Vendor › Dates | `vendor.last_assessed_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | No |
| Vendor Uploaded Date | Vendor › Documents | `vendor.documents.created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Vendor | Vendor | `vendor.id` | Reference | Vendors in your workspace | is, is not, any of, none of | No |
| Vendor Assessment Count | Vendor › Assessments | `vendor.assessments.count` | Number | - | at least, at most, is, is not | No |
| Vendor Assessment Outcome | Vendor | `vendor.last_assessment_outcome` | Reference | Approval options in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Inherent Risk Level | Vendor | `vendor.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Inherent Risk Score | Vendor | `vendor.raw_irq_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Name | Vendor | `vendor.name` | Text | - | is, is not, any of, none of, contains, does not contain | No |
| Vendor Relationship Owners | Vendor | `vendor.relationship_owners` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Residual Risk Level | Vendor | `vendor.residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Residual Risk Score | Vendor | `vendor.raw_residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Risk Analysts | Vendor | `vendor.risk_analysts` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Risk Domain Inherent Risk Level | Vendor | `vendor.risk_domain_scores.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Risk Domain Inherent Risk Score | Vendor | `vendor.risk_domain_scores.inherent_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Risk Domain Residual Risk Level | Vendor | `vendor.risk_domain_scores.residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Risk Domain Residual Risk Score | Vendor | `vendor.risk_domain_scores.residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Risk Domains | Vendor | `vendor.risk_domain_scores.risk_domain_id` | Reference | Risk domains in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Status | Vendor | `vendor.status_id` | Reference | Vendor statuses in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Tags | Vendor | `vendor.tags` | Multi-reference | Tags in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Watchers | Vendor | `vendor.watchers` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Website | Vendor | `vendor.website` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| Vendor Archived | Vendor | `vendor.is_archived` | Yes/No | - | is, is not | No |
| Vendor Tier | Vendor | `vendor.tier` | Choice | `tier_1`, `tier_2`, `tier_3`, `tier_4` | is, is not, any of, none of, empty, not empty | No |
| Name | - | `name` | Text | - | is, is not, any of, none of, contains, does not contain | Yes |
| Service | - | `services` | Multi-reference | - | any of, none of, all of, not all of, empty, not empty | No |
| Source | - | `document_source` | Choice | `manual_upload`, `system_generated`, `bulk_upload`, `email_attachment`, `email_correspondence`, `portal`, `safebase`, `grc_scrape`, `onetrust`, `processunity`, `wss`, `document_library`, `trust_center` | is, is not, any of, none of | Yes |
| Status | - | `status` | Choice | `created`, `unzipping`, `analyzing`, `queued_processing`, `complete`, `failed`, `locked` | is, is not, any of, none of | Yes |
| Type | - | `document_type` | Choice | Document types in your workspace | is, is not, any of, none of, empty, not empty | Yes |
| Uploaded Date | - | `created_at` | Date | - | after, before, on or after, on or before, between | Yes |
| Size | - | `size` | Number | - | greater than, less than, at least, at most, between | Yes |
## Assessments
The **Assessments** list and assessment records, including zero-touch runs.
**67 fields**, queryable at `POST /v1/assessment/query`, available in saved views, usable as the `assessment` target in workflow conditions, extendable with custom fields.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Name | - | `name` | Text | - | is, is not, any of, none of, contains, does not contain | Yes |
| Created | Dates | `created_at` | Date | - | after, before, on or after, on or before, between | Yes |
| Initiated Date | Dates | `initiated_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | No |
| Updated Date | Dates | `updated_at` | Date | - | after, before, on or after, on or before, between | Yes |
| Document Types | Documents | `supporting_documents.document_type` | Choice | Document types in your workspace | any of, none of, all of, not all of | No |
| Document Count | Documents | `supporting_documents.count` | Number | - | at least, at most, is, is not | No |
| Document Handoff | Documents | `doc_collection_handoff_metadata` | Structured | - | empty, not empty | No |
| Uploaded Date | Documents | `supporting_documents.created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Review Status | Reviews | `reviews.status_id` | Reference | Review statuses in your workspace | is, all are, is not, any of, none of, empty, not empty | No |
| Reviewer | Reviews | `reviews.assignee_ref` | Reference | Users and groups in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor | Vendor | `vendor.id` | Reference | Vendors in your workspace | is, is not, any of, none of | Yes |
| Vendor Archived | Vendor | `vendor.is_archived` | Yes/No | - | is, is not | No |
| Vendor Tags | Vendor | `vendor.tags` | Multi-reference | Tags in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Inherent Risk Level | Vendor | `vendor.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | Yes |
| Vendor Inherent Risk Score | Vendor | `vendor.raw_irq_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Residual Risk Level | Vendor | `vendor.residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Residual Risk Score | Vendor | `vendor.raw_residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Relationship Owners | Vendor | `vendor.relationship_owners` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Risk Analysts | Vendor | `vendor.risk_analysts` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Watchers | Vendor | `vendor.watchers` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Status | Vendor | `vendor.status_id` | Reference | Vendor statuses in your workspace | is, is not, any of, none of, empty, not empty | No |
| Next Assessment Date | Vendor | `vendor.next_assessment_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Vendor Risk Domains | Vendor | `vendor.risk_domain_scores.risk_domain_id` | Reference | Risk domains in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Risk Domain Inherent Risk Score | Vendor | `vendor.risk_domain_scores.inherent_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Risk Domain Inherent Risk Level | Vendor | `vendor.risk_domain_scores.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Risk Domain Residual Risk Score | Vendor | `vendor.risk_domain_scores.residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Risk Domain Residual Risk Level | Vendor | `vendor.risk_domain_scores.residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Tier | Vendor | `vendor.tier` | Choice | `tier_1`, `tier_2`, `tier_3`, `tier_4` | is, is not, any of, none of, empty, not empty | No |
| Vendor Last Assessed | Vendor | `vendor.last_assessed_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | No |
| Status | - | `status_id` | Reference | Assessment statuses in your workspace | is, is not, any of, none of, empty, not empty | Yes |
| Portal State | - | `portal_state` | Choice | `open`, `submitted`, `closed`, `overdue` | is, is not, any of, none of, empty, not empty | No |
| Risk Type | - | `risk_type` | Choice | `inherent_risk`, `residual_risk`, `untargeted` | is, is not, any of, none of | No |
| Inherent Risk Level | - | `inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Inherent Risk Score | - | `irq_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| SLA Breach Count | - | `sla_breach_count` | Number | - | is, is not, greater than, at least, less than, at most, between | Yes |
| Document submission days | - | `sla_doc_submission_elapsed_seconds` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | Yes |
| Reviewer review days | - | `sla_review_elapsed_seconds` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | Yes |
| Email Count | Emails | `emails.count` | Number | - | at least, at most, is, is not | No |
| Follow-up response days | - | `sla_follow_up_elapsed_seconds` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | Yes |
| Finding commitments days | - | `sla_commitment_elapsed_seconds` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | Yes |
| Control Sets | - | `policy_control_sets` | Multi-reference | Control sets in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Risk Domains | - | `risk_domain_scores.risk_domain_id` | Reference | Risk domains in your workspace | is, is not, any of, none of, empty, not empty | No |
| Risk Domain Residual Risk Level | - | `risk_domain_scores.residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Risk Domain Reviewer | - | `risk_domain_scores.reviewer_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Risk Domain Score Sum | - | `risk_domain_scores.score_sum` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Risk Domain Score Average | - | `risk_domain_scores.score_average` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Issue Count | - | `issues.count` | Number | - | at least, at most, is, is not | No |
| Risk Domain Score Percent | - | `risk_domain_scores.score_percent` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Finding Count | - | `findings.count` | Number | - | at least, at most, is, is not | No |
| Assessment Plan | - | `assessment_plan_id` | Reference | Assessment plans in your workspace | is, is not, any of, none of, empty, not empty | No |
| Assignee | - | `assignee_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Is Zero Touch run | - | `is_zero_touch` | Yes/No | - | is, is not | No |
| Outcome | - | `approval_option_id` | Reference | Approval options in your workspace | is, is not, any of, none of, empty, not empty | Yes |
| Submitted by | - | `created_by_id` | Reference | Users in your workspace | is, is not, any of, none of | No |
| Zero Touch score | - | `zero_touch_composite_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | Yes |
| Stage | - | `lifecycle_status.key` | Choice | `created`, `collecting_documents`, `analyzing_controls`, `review_results`, `complete`, `failed`, `canceled` | is, is not, any of, none of, empty, not empty | No |
| Awaiting Response | - | `is_awaiting_follow_up_response` | Yes/No | - | is, is not | No |
| Has Open Issue | - | `has_open_issue` | Yes/No | - | is, is not | No |
| Risk Domain SLA Breach Count | - | `sla_domain_breach_count` | Number | - | is, is not, greater than, at least, less than, at most, between | Yes |
| Review Risk Domains | - | `domain_reviews.assessment_association.risk_domain_id` | Reference | Risk domains in your workspace | is, is not, any of, none of, empty, not empty | No |
| Review Status | - | `domain_reviews.status_id` | Reference | Review statuses in your workspace | is, is not, any of, none of, empty, not empty | No |
| Control Outcome | Controls | `evals.outcome` | Choice | `issue`, `not_an_issue`, `mitigated`, `risk_accepted`, `resolved` | is, is not, any of, none of | No |
| Control Is An Issue | Controls | `evals.is_issue` | Yes/No | - | is, is not | No |
| Control Is Resolved | Controls | `evals.is_resolved` | Yes/No | - | is, is not | No |
| Control Confidence | Controls | `evals.confidence` | Choice | `low`, `medium`, `high` | is, is not, any of, none of, empty, not empty | No |
| Control Set | Controls | `evals.control.control_set_id` | Reference | Control sets in your workspace | is, is not, any of, none of | No |
| Control Count | Controls | `evals.count` | Number | - | at least, at most, is, is not | No |
## Assessment responses
The control-by-control response list inside an assessment.
**27 fields**, queryable at `POST /v1/eval/query`, available in saved views, usable as the `eval` target in workflow conditions, extendable with custom fields.
Default sort: `public_idx` asc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| AI-generated response | - | `ai_response_value` | Text | - | is, is not, any of, none of | No |
| Category | - | `issue_category` | Choice | `incomplete_response`, `missing_document`, `violates_policy`, `inconsistency`, `subpar_practices`, `acceptable`, `needs_review`, `condition_not_met`, `unknown` | is, is not, any of, none of, empty, not empty | No |
| Confidence | - | `confidence` | Choice | `low`, `medium`, `high` | is, is not, any of, none of, empty, not empty | No |
| Control Section | - | `control.control_section_id` | Reference | - | is, is not, any of, none of, empty, not empty | Yes |
| Control Set | - | `control.control_set_id` | Reference | Control sets in your workspace | is, is not, any of, none of, empty, not empty | No |
| Control Weight | - | `control.weight` | Number | - | is, is not, greater than, at least, less than, at most, between | No |
| Control identifier | - | `public_idx` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | Yes |
| Current follow-up status | - | `latest_follow_up_status` | Choice | `draft`, `open`, `closed` | is, is not, any of, none of, empty, not empty | No |
| Follow-up item status | - | `follow_up_items.status` | Choice | `draft`, `open`, `closed` | any of, none of | No |
| Follow-up round status | - | `follow_up_items.follow_up_section.status` | Choice | `not_yet_sent`, `awaiting_response`, `response_received` | is, is not, any of, none of | No |
| Issue status | - | `is_issue` | Yes/No | - | is, is not | No |
| Linked Findings | - | `tasks.count` | Number | - | at least, at most, is, is not | No |
| Question | - | `question` | Text | - | contains, does not contain | Yes |
| Questionnaire | - | `source_obj_id` | Reference | - | is, is not, any of, none of, empty, not empty | Yes |
| Resolution status | - | `is_resolved` | Yes/No | - | is, is not | No |
| Response | - | `has_response` | Yes/No | - | is, is not | No |
| Response origin | - | `is_response_generated` | Yes/No | - | is, is not | No |
| Response review status | - | `response_alignment` | Choice | `aligned`, `discrepancy`, `resolved` | is, is not, any of, none of | No |
| Response text | - | `response` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | Yes |
| Review Notes | - | `review_notes` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| Reviewer | - | `control.control_set.reviewers` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Scale | - | `scores.scale_level.scale_id` | Reference | Scales in your workspace | is, is not, any of, none of, empty, not empty | No |
| Scale Level | - | `scores.scale_level_id` | Reference | Scale levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Score | - | `scores.scale_level.value` | Number | - | is, is not, greater than, at least, less than, at most, between | Yes |
| Title | - | `title` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| Notes | - | `has_notes` | Yes/No | - | is, is not | No |
| Mentioned | - | `mentioned_users` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
## Findings
The **Findings** list and finding records.
**12 fields**, queryable at `POST /v1/finding/query`, available in saved views, usable as the `finding` target in workflow conditions, extendable with custom fields.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Vendor | - | `resolved_vendor_id` | Reference | Vendors in your workspace | is, is not, any of, none of, empty, not empty | Yes |
| Status | - | `finding_status_id` | Reference | Finding statuses in your workspace | is, is not, any of, none of | Yes |
| Due Date | Dates | `due_date` | Date | - | after, before, on or after, on or before, between, empty, not empty | Yes |
| Created Date | Dates | `created_at` | Date | - | after, before, on or after, on or before, between | Yes |
| Updated Date | Dates | `updated_at` | Date | - | after, before, on or after, on or before, between | Yes |
| Assignee | - | `assigned_to_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | Yes |
| Created By | - | `created_by_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Source Type | - | `source_type` | Choice | `assessment`, `vendor`, `org_document`, `radar_alert`, `contract`, `inspect_evaluation`, `screening_match`, `risk`, `dark_web_exposure` | is, is not, any of, none of | No |
| Source document | - | `extraction_source_document_id` | Reference | Finding source documents in your workspace | is, is not, any of, none of | No |
| Risk Level | - | `finding_risk_level_id` | Reference | Finding risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Control Set | - | `evals.control.control_set_id` | Reference | Control sets in your workspace | is, is not, any of, none of | No |
| Commitment Count | - | `commitments.count` | Number | - | at least, at most, is, is not | No |
## Commitments
The **Commitments** tab under Findings, and the commitments on a finding.
**16 fields**, queryable at `POST /v1/commitment/query`, available in saved views.
Default sort: `due_at` asc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Vendor | - | `finding.vendor_id` | Reference | Vendors in your workspace | is, is not, any of, none of, empty, not empty | Yes |
| Finding Assignee | - | `finding.assigned_to_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Assignee | - | `assigned_to_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Status | - | `commitment_status` | Choice | `pending_response`, `negotiating`, `mitigation_underway`, `declined`, `closed` | is, is not, any of, none of | Yes |
| Due Date | Dates | `due_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | Yes |
| Created Date | Dates | `created_at` | Date | - | after, before, on or after, on or before, between | Yes |
| Updated Date | Dates | `updated_at` | Date | - | after, before, on or after, on or before, between | No |
| Committed Date | Dates | `committed_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | No |
| Vendor Proposed Date | Dates | `vendor_proposed_date` | Date | - | after, before, on or after, on or before, between, empty, not empty | No |
| Awaiting Response Since | Dates | `awaiting_response_since` | Date | - | after, before, on or after, on or before, between, empty, not empty | Yes |
| Response State | - | `response_state` | Choice | `awaiting_response`, `response_overdue`, `awaiting_review`, `none` | is, is not, any of, none of | No |
| Vendor Response | - | `vendor_response_type` | Choice | `accepted`, `counter_proposed`, `compensating_control`, `declined`, `completed` | is, is not, any of, none of, empty, not empty | No |
| Description | - | `description` | Text | - | contains, does not contain, empty, not empty | No |
| Vendor Satisfied | - | `is_vendor_satisfied` | Yes/No | - | is, is not | No |
| Org Satisfied | - | `is_org_satisfied` | Yes/No | - | is, is not | No |
| Sent to Vendor | - | `portal_id` | Reference | - | empty, not empty | No |
## Reviews
Review steps on contracts, procurement requests, and assessments. These fields are also spliced into the parent record's filters as `reviews.*`.
**5 fields**, usable as the `review` target in workflow conditions.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Name | - | `name` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | Yes |
| Status | - | `status_id` | Reference | Review statuses in your workspace | is, is not, any of, none of, empty, not empty | Yes |
| Reviewer | - | `assignee_ref` | Reference | Users and groups in your workspace | is, is not, any of, none of, empty, not empty | No |
| Review Context | - | `review_context` | Choice | `contract`, `procurement`, `assessment`, `assessment_risk_domain`, `radar_signal` | is, is not, any of, none of | No |
| Decision | - | `status.key` | Choice | `queued`, `started`, `accept`, `reject` | is, is not, any of, none of, empty, not empty | No |
## Vendor intake
The **Intake** list of intake sessions.
**6 fields**, queryable at `POST /v1/intake_session/query`, available in saved views, usable as the `intake` target in workflow conditions.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Assignee | - | `assignee_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Created Date | - | `created_at` | Date | - | after, before, on or after, on or before, between | Yes |
| Source | - | `source` | Choice | `portal`, `api` | is, is not, any of, none of | No |
| Status | - | `status` | Choice | `open`, `submitted`, `pending_review`, `rejected`, `accepted`, `partial` | is, is not, any of, none of | No |
| Submitted Date | - | `submitted_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | No |
| Vendor | - | `vendor_id` | Reference | Vendors in your workspace | is, is not, any of, none of, empty, not empty | No |
## Procurement requests
Procurement requests raised from intake.
**4 fields**, usable as the `procurement` target in workflow conditions.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Procurement | - | `id` | Reference | - | is, is not, any of, none of | No |
| Review Status | Reviews | `reviews.status_id` | Reference | Review statuses in your workspace | is, all are, is not, any of, none of, empty, not empty | No |
| Reviewer | Reviews | `reviews.assignee_ref` | Reference | Users and groups in your workspace | is, is not, any of, none of, empty, not empty | No |
| Status | - | `status_id` | Reference | Procurement statuses in your workspace | is, is not, any of, none of, empty, not empty | Yes |
## Portals
The **Portals** list of vendor-facing collection portals.
**8 fields**, queryable at `POST /v1/portal/query`, available in saved views.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Status | - | `status` | Choice | `open`, `analyzing`, `analysis_complete`, `submitted`, `closed` | is, is not, any of, none of | No |
| Due Date | Dates | `due_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Created Date | Dates | `created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Type | - | `type` | Choice | `assessment`, `intake`, `irq`, `vendor_onboarding`, `informational`, `findings_commitment`, `obligation_commitment`, `vendor_search`, `rfp`, `case`, `signature` | is, is not, any of, none of | No |
| Lifecycle | - | `lifecycle` | Choice | `ephemeral`, `persistent` | is, is not, any of, none of | No |
| Vendor | - | `vendor_id` | Reference | Vendors in your workspace | is, is not, any of, none of, empty, not empty | No |
| Number of Asks | - | `asks.count` | Number | - | at least, at most, is, is not | No |
| Number of Documents | - | `vendor_documents.count` | Number | - | at least, at most, is, is not | No |
## Radar signals
The **Signals** tab in Supplier Radar. One row per event your organization is exposed to.
**14 fields**, queryable at `POST /v1/radar_signal/query`, available in saved views.
Default sort: `last_alerted_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Vendor | Vendor | `vendor_id` | Reference | Vendors in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor inherent risk level | Vendor | `vendor_inherent_risk_level_id` | Reference | Risk levels in your workspace | any of, none of, is, any of, empty, not empty | No |
| Tier | Vendor | `vendor_tier` | Choice | `tier_1`, `tier_2`, `tier_3`, `tier_4` | any of, none of, is, any of, empty, not empty | No |
| Detector | - | `detector_id` | Reference | Radar detectors in your workspace | is, is not, any of, none of, empty, not empty | No |
| Status | - | `status` | Choice | `confirmed`, `open`, `dismissed`, `tracked`, `alerting`, `triaged`, `closed` | is, is not, any of, none of | No |
| Name | - | `name` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| Risk domain | - | `risk_domain_id` | Reference | Risk domains in your workspace | is, is not, any of, none of, empty, not empty | No |
| Summary | - | `summary` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| Last alerted | Dates | `last_alerted_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | Yes |
| First seen | Dates | `first_seen_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | Yes |
| Severity | - | `severity` | Choice | `high`, `medium`, `low`, `informational` | is, is not, any of, none of, empty, not empty | Yes |
| Status | - | `status_id` | Reference | Signal statuses in your workspace | is, is not, any of, none of, empty, not empty | No |
| Nth party inherent risk level | - | `event.radar_event_entity_relationships.entity.subprocessors.inherent_risk_level_id` | Reference | Risk levels in your workspace | any of, none of, is, any of, empty, not empty | No |
| Nth party tags | - | `event.radar_event_entity_relationships.entity.subprocessors.tags` | Multi-reference | Tags in your workspace | any of, none of, all of, not all of, empty, not empty | No |
### Radar signals in workflow conditions
The `radar_signal` target in workflow conditions filters the same rows through a smaller field set, and its paths differ from the Signals tab: severity is `max_severity`, and detector and vendor are matched through the signal's alerts.
**33 fields**, usable as the `radar_signal` target in workflow conditions.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Status | - | `status` | Choice | `confirmed`, `open`, `dismissed`, `tracked`, `alerting`, `triaged`, `closed` | is, is not, any of, none of | No |
| Severity | - | `max_severity` | Choice | `high`, `medium`, `low`, `informational` | is, is not, any of, none of, empty, not empty | No |
| Detector | - | `members.detector_id` | Reference | Radar detectors in your workspace | is, is not, any of, none of, empty, not empty | No |
| Lifecycle status | - | `status_id` | Reference | Signal statuses in your workspace | is, is not, any of, none of, empty, not empty | No |
| Name | - | `name` | Text | - | is, is not, contains, does not contain, empty, not empty | No |
| Summary | - | `summary` | Text | - | is, is not, contains, does not contain, empty, not empty | No |
| Archived | - | `is_archived` | Yes/No | - | is, is not | No |
| Alert severity | - | `members.severity` | Choice | `high`, `medium`, `low`, `informational` | is, is not, any of, none of | No |
| Nth party inherent risk level | - | `event.radar_event_entity_relationships.entity.subprocessors.inherent_risk_level_id` | Reference | Risk levels in your workspace | any of, none of, is, any of, empty, not empty | No |
| Nth party tags | - | `event.radar_event_entity_relationships.entity.subprocessors.tags` | Multi-reference | Tags in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor | Vendor | `members.vendor_id` | Reference | Vendors in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Tags | Vendor | `members.vendor.tags` | Multi-reference | Tags in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Archived | Vendor | `members.vendor.is_archived` | Yes/No | - | is, is not | No |
| Vendor Risk Analysts | Vendor | `members.vendor.risk_analysts` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Relationship Owners | Vendor | `members.vendor.relationship_owners` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Watchers | Vendor | `members.vendor.watchers` | Multi-reference | Users in your workspace | any of, none of, all of, not all of, empty, not empty | No |
| Vendor Status | Vendor | `members.vendor.status_id` | Reference | Vendor statuses in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Tier | Vendor | `members.vendor.tier` | Choice | `tier_1`, `tier_2`, `tier_3`, `tier_4` | is, is not, any of, none of, empty, not empty | No |
| Vendor Inherent Risk Level | Vendor | `members.vendor.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Residual Risk Level | Vendor | `members.vendor.residual_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Assessment Outcome | Vendor | `members.vendor.last_assessment_outcome` | Reference | Approval options in your workspace | is, is not, any of, none of, empty, not empty | No |
| Vendor Inherent Risk Score | Vendor | `members.vendor.raw_irq_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Residual Risk Score | Vendor | `members.vendor.raw_residual_risk_score` | Number | - | is, is not, greater than, at least, less than, at most, between, empty, not empty | No |
| Vendor Website | Vendor | `members.vendor.website` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| Created date | Dates | `created_at` | Date | - | after, before, on or after, on or before, between | Yes |
| First seen | Dates | `first_seen_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | Yes |
| Last alerted | Dates | `last_alerted_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | Yes |
| Confirmed date | Dates | `confirmed_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | No |
| Vendor Created Date | Vendor › Dates | `members.vendor.created_at` | Date | - | after, before, on or after, on or before, between | No |
| Vendor Next Assessment Date | Vendor › Dates | `members.vendor.next_assessment_date` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Vendor Last Assessed | Vendor › Dates | `members.vendor.last_assessed_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | No |
| Review status | Reviews | `reviews.status_id` | Reference | Review statuses in your workspace | is, all are, is not, any of, none of, empty, not empty | No |
| Reviewer | Reviews | `reviews.assignee_ref` | Reference | Users and groups in your workspace | is, is not, any of, none of, empty, not empty | No |
## Radar cases
The **Cases** tab in Supplier Radar.
**7 fields**, queryable at `POST /v1/case/query`.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Title | - | `title` | Text | - | is, is not, any of, none of, contains, does not contain | Yes |
| Status | - | `status` | Choice | `open`, `closed` | is, is not, any of, none of | No |
| Resolution | - | `resolution` | Choice | `resolved`, `false_positive`, `wont_fix` | is, is not, any of, none of, empty, not empty | No |
| Assignee | - | `assignee_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Created By | - | `created_by_id` | Reference | Users in your workspace | is, is not, any of, none of | No |
| Created Date | Dates | `created_at` | Date | - | after, before, on or after, on or before, between | Yes |
| Updated Date | Dates | `updated_at` | Date | - | after, before, on or after, on or before, between | Yes |
## Radar case vendor threads
The per-vendor thread list inside a Radar case.
**6 fields**, queryable at `POST /v1/case/{case_id}/thread/query`.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Assignee | - | `assignee_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Created Date | - | `created_at` | Date | - | after, before, on or after, on or before, between | Yes |
| Due Date | - | `due_date` | Date | - | after, before, on or after, on or before, between, empty, not empty | Yes |
| Inherent Risk Level | - | `vendor.inherent_risk_level_id` | Reference | Risk levels in your workspace | is, is not, any of, none of, empty, not empty | No |
| Status | - | `status` | Choice | `open`, `email_sent`, `response_received`, `in_review`, `assessment_triggered`, `on_hold`, `closed` | is, is not, any of, none of | Yes |
| Tags | - | `vendor.tags` | Multi-reference | Tags in your workspace | any of, none of, all of, not all of, empty, not empty | No |
## Radar sources
The **Sources** tab in Radar configuration.
**3 fields**, queryable at `POST /v1/radar_source/query`.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Name | - | `name` | Text | - | is, is not, any of, none of, contains, does not contain | Yes |
| Active | - | `origin.is_enabled` | Yes/No | - | is, is not | No |
| Created Date | Dates | `created_at` | Date | - | after, before, on or after, on or before, between | Yes |
## Nth-party entities
The nth-party graph and the subprocessor lists on a vendor.
**14 fields**, queryable at `POST /v1/nth_party/query`, available in saved views.
Default sort: `name` asc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Nth Party Name | - | `name` | Text | - | is, is not, any of, none of, contains, does not contain | Yes |
| Created Date | Dates | `created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Updated Date | Dates | `updated_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Website | - | `website` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | Yes |
| Description | - | `description` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| HQ Location | - | `hq_location` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| Security Contact Email | - | `security_contact_email` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| Trust Center URL | - | `trust_center_url` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | No |
| Company Status | - | `company_status` | Choice | `private`, `public`, `acquired/merged`, `defunct` | is, is not, any of, none of, empty, not empty | No |
| Scanned Facts Status | - | `scanned_facts_status` | Choice | `pending`, `completed`, `failed` | is, is not, any of, none of, empty, not empty | No |
| Nth Party | - | `id` | Reference | Nth-party entities in your workspace | is, is not, any of, none of | No |
| Dependent Vendor Inherent Risk Level | - | `dependent_vendors.inherent_risk_level_id` | Reference | Risk levels in your workspace | any of, none of, all of, not all of | No |
| Inherent Risk Level | - | `subprocessors.inherent_risk_level_id` | Reference | Risk levels in your workspace | any of, none of, all of, not all of | No |
| Tags | - | `subprocessors.tags` | Multi-reference | Tags in your workspace | any of, none of, all of, not all of, empty, not empty | No |
## Work queue
The **Work Queue** list of tasks assigned to your team.
**13 fields**, queryable at `POST /v1/work_queue_item/query`, usable as the `work_queue_item` target in workflow conditions.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Type | - | `type` | Choice | `procurement_review`, `assessment_review`, `assessment_domain_review`, `contract_review`, `intake_submission_review`, `document_collection_handoff`, `intake_request_review`, `clause_review`, `assessment_control_set_review`, `questionnaire_response_review`, `risk_review`, `radar_signal_review`, `reassessment_scoping` | is, is not, any of, none of | Yes |
| Status | - | `status` | Choice | `pending`, `completed`, `canceled` | is, is not, any of, none of | No |
| Assignee | - | `assigned_user_id` | Reference | Users in your workspace | is, is not, any of, none of | Yes |
| Vendor | - | `vendor_id` | Reference | Vendors in your workspace | is, is not, any of, none of | Yes |
| Assessment | - | `assessment_id` | Reference | - | is, is not, any of, none of, empty, not empty | No |
| Resolved Date | Dates | `completed_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | Yes |
| Due Date | Dates | `due_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | Yes |
| Created Date | Dates | `created_at` | Date | - | after, before, on or after, on or before, between | Yes |
| Updated Date | Dates | `updated_at` | Date | - | after, before, on or after, on or before, between | Yes |
| Created By | - | `created_by_user_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Resolved By | - | `completed_by_user_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Title | - | `title` | Text | - | contains, does not contain, is, is not | Yes |
| Waiting on Vendor | - | `is_waiting_on_vendor` | Yes/No | - | is, is not | No |
## Questionnaire responses
The **Questionnaires** tab on a vendor: the questionnaires sent to that vendor and their responses.
**14 fields**, queryable at `POST /v1/questionnaire_response/query`, usable as the `questionnaire_response` target in workflow conditions.
Default sort: `sent_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Status | - | `status` | Choice | `pending`, `processing`, `processing_complete`, `processing_failed`, `submitted`, `ready_for_review`, `approved`, `rejected` | is, is not, any of, none of | Yes |
| Questionnaire | Questionnaire | `questionnaire_id` | Reference | Questionnaires in your workspace | is, is not, any of, none of, empty, not empty | No |
| Questionnaire Name | Questionnaire | `questionnaire.name` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | Yes |
| Questionnaire Type | Questionnaire | `questionnaire.type` | Choice | `irq`, `vendor_onboarding`, `assessment`, `informational`, `follow_up`, `rfp_prequalification`, `rfp_response`, `performance`, `kys` | is, is not, any of, none of | Yes |
| Assessment | Assessment | `assessment_id` | Reference | Assessments in your workspace | is, is not, any of, none of, empty, not empty | No |
| Assessment Name | Assessment | `assessment.name` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | Yes |
| Vendor | - | `vendor_id` | Reference | Vendors in your workspace | is, is not, any of, none of, empty, not empty | No |
| Reviewer | - | `assignee_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Respondent | - | `respondent_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Sent By | - | `sent_by_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Sent Date | Dates | `sent_at` | Date | - | after, before, on or after, on or before, between | Yes |
| Submitted Date | Dates | `submitted_at` | Date | - | after, before, on or after, on or before, between, empty, not empty | Yes |
| Created Date | Dates | `created_at` | Date | - | after, before, on or after, on or before, between | Yes |
| Updated Date | Dates | `updated_at` | Date | - | after, before, on or after, on or before, between | Yes |
## Signature envelopes
The **Signatures** list under Contracts.
**13 fields**, queryable at `POST /v1/signature/envelope/query`.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Name | - | `name` | Text | - | is, is not, any of, none of, contains, does not contain, empty, not empty | Yes |
| Status | - | `status` | Choice | `draft`, `sent`, `delivered`, `partially_signed`, `completed`, `declined`, `voided`, `expired`, `failed` | is, is not, any of, none of | Yes |
| Signing Engine | - | `signing_engine` | Choice | `native`, `docusign` | is, is not, any of, none of | No |
| Vendor | - | `vendor_id` | Reference | Vendors in your workspace | is, is not, any of, none of, empty, not empty | No |
| Sender | - | `created_by_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Sent Date | Dates | `sent_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Completed Date | Dates | `completed_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Expiry Date | Dates | `expires_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Created Date | Dates | `created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Updated Date | Dates | `updated_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Verifies Signers | - | `require_signer_verification` | Yes/No | - | is, is not | No |
| Party Count | Parties | `recipients.count` | Number | - | at least, at most, is, is not | No |
| Document Count | Documents | `documents.count` | Number | - | at least, at most, is, is not | No |
## Inspect identities
The identities list in Agentic Inspect.
**22 fields**, queryable at `POST /v1/inspect/identities/query`, available in saved views.
Default sort: `display_name` asc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Name | - | `display_name` | Text | - | is, is not, contains, does not contain, empty, not empty | Yes |
| Email | - | `primary_email` | Text | - | is, is not, contains, does not contain, empty, not empty | No |
| Identity basis | - | `association` | Choice | `directory`, `email_match`, `observed_only`, `ambiguous` | is, is not, any of, none of | No |
| Number of accounts | - | `account_count` | Number | - | at least, at most, is, is not | Yes |
| Accounts with admin observed | - | `admin_account_count` | Number | - | at least, at most, is, is not | Yes |
| Accounts needing review | - | `needs_review_count` | Number | - | at least, at most, is, is not | No |
| Latest observation | - | `latest_observed_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Added | - | `created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
| Identity provider | Directory | `principals.provider` | Choice | `okta`, `entra` | is, is not, any of, none of | No |
| Directory type | Directory | `principals.member_kind` | Choice | `member`, `guest`, `unknown` | is, is not, any of, none of | No |
| Directory account enabled | Directory | `principals.enabled` | Yes/No | - | is, is not, empty, not empty | No |
| Number of directory records | Directory | `principals.count` | Number | - | at least, at most, is, is not | No |
| Directory lifecycle | Directory | `principals.supported_detections.classification` | Choice | `disabled`, `inactive`, `dormant`, `guest`, `external`, `non_human`, `idp_removed_still_active` | is, is not, any of, none of | No |
| Application | Application account | `accounts.application_id` | Reference | Applications in your workspace | is, is not, any of, none of | No |
| Account basis | Application account | `accounts.attribution` | Choice | `provider_assignment`, `email_match`, `observed_only`, `ambiguous` | is, is not, any of, none of | No |
| Synced account status | Application account | `accounts.status` | Choice | `enabled`, `disabled`, `unknown` | is, is not, any of, none of | No |
| Needs review | Application account | `accounts.needs_review` | Yes/No | - | is, is not | No |
| Attributed observations | Application account | `accounts.evidence_count` | Number | - | at least, at most, is, is not | No |
| Last observed | Application account | `accounts.latest_observed_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Admin observed (historical) | Application account | `accounts.admin_observed_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | No |
| Latest observed admin state | Application account | `accounts.latest_admin_state` | Choice | `admin`, `not_admin`, `unknown` | is, is not, any of, none of | No |
| Account lifecycle | Application account | `accounts.supported_detections.classification` | Choice | `disabled`, `inactive`, `dormant`, `guest`, `external`, `non_human`, `idp_removed_still_active` | is, is not, any of, none of | No |
## Inspect inspections
The inspections list in Agentic Inspect.
**7 fields**, queryable at `POST /v1/inspect/inspections/query`, available in saved views.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Application | - | `app_name` | Text | - | is, is not, any of, none of, contains, does not contain | No |
| Status | - | `status` | Choice | `created`, `running`, `succeeded`, `partial`, `blocked`, `failed` | is, is not, any of, none of | No |
| Purpose | - | `purpose` | Choice | `evaluative`, `exploratory`, `drift`, `probe` | is, is not, any of, none of | No |
| Vendor | - | `vendor_id` | Reference | Vendors in your workspace | is, is not, any of, none of, empty, not empty | No |
| Probe | - | `probe_id` | Reference | Probes in your workspace | is, is not, any of, none of, empty, not empty | No |
| Requested By | - | `requested_by_user_id` | Reference | Users in your workspace | is, is not, any of, none of, empty, not empty | No |
| Created Date | - | `created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
## Inspect probes
The probes list in Agentic Inspect.
**4 fields**, queryable at `POST /v1/inspect/probes/query`.
Default sort: `created_at` desc.
| Field | Group | Filter path | Type | Values | Operators | Sortable |
| - | - | - | - | - | - | - |
| Probe | - | `id` | Reference | Probes in your workspace | is, is not, any of, none of | No |
| Application | - | `target.display_name` | Text | - | is, is not, any of, none of, contains, does not contain | No |
| Automation | - | `is_paused` | Yes/No | - | is, is not | No |
| Created Date | - | `created_at` | Date | - | after, on or after, before, on or before, between, empty, not empty | Yes |
# Field reference
Source: https://docs.coverbase.com/fields/overview
How Coverbase fields work across filters, saved views, sorting, workflow conditions, and the query API.
Every core module in Coverbase is backed by one published set of fields. That
same set drives the dashboard and the API, so a field you can filter on in a
list is a field you can sort by, save into a view, branch a workflow on, and
query programmatically, under the same name.
The **Add filter** menu on every list page is built from this field set. A
saved view stores the filter tree, the sort, and the visible columns.
Fields marked sortable can order any list page or query response.
Automations evaluate the same fields against a target record. See
[Workflow engine](/integrations/workflow-engine).
`POST /v1//query` accepts the same field paths as a JSON rule tree.
## Reading the catalog
The [field catalog](/fields/catalog) lists every field by module. Each row gives
you:
| Column | What it means |
| - | - |
| **Field** | The label shown in the dashboard. |
| **Group** | The submenu the field sits under in the **Add filter** menu, or `-` for a top-level field. |
| **Filter path** | The identifier used by the query API, saved views, and workflow conditions. |
| **Type** | The kind of value the field holds, which decides the available operators. |
| **Values** | For choice fields, the accepted values. For reference fields, the workspace list the picker reads from. |
| **Operators** | The comparisons the field supports. |
| **Sortable** | Whether lists and query responses can be ordered by the field. |
### Field types
| Type | Description |
| - | - |
| Text | Free text. Supports substring matching. |
| Number | Numeric value, including counts of related records. |
| Date | A point in time. The dashboard picker also offers relative windows such as "1 month ago". |
| Yes/No | A boolean flag. |
| Choice | A fixed set of values defined by Coverbase. |
| Reference | A pointer to one other record, such as a user or a status. |
| Multi-reference | A set of related records, such as tags or owners. |
| Structured | A nested object. Filters can only test whether it is empty. |
### Operators
| Operator | Applies to | Meaning |
| - | - | - |
| is / is not | Most types | Exact match against a single value. |
| any of / none of | Text, Choice, Reference | Match against a list of values. |
| contains / does not contain | Text | Substring match. |
| after / on or after / before / on or before | Date | Compare against a point in time. |
| greater than / at least / less than / at most | Number | Numeric comparison. |
| between | Date, Number | Inclusive range, given as `{"from": ..., "to": ...}`. |
| any of / none of | Multi-reference | The record is related to at least one, or none, of the selected values. |
| all of / not all of | Multi-reference, and choice or reference fields on related records | The record is related to every selected value. Extra values still match. |
| all are | Reference fields on related records | Every related record equals the selected value. |
| empty / not empty | Most types | The field has no value, or has any value. |
## Fields this catalog does not list
Custom fields are defined per workspace, so they cannot be listed here.
Custom fields can be attached to vendors, services, engagements, contracts,
assessments, assessment responses, controls, findings, and reviews. Once
configured, they appear alongside the built-in fields in the filter menus
for vendors, services, contracts, assessments, assessment responses, and
findings. Engagement and review custom fields are not filterable. See
[Custom fields](/api-reference/custom-fields).
Your workspace can rename core terms: vendor, service, action, task,
finding, follow-up, issue, assessment, and control. Labels in this catalog
use the Coverbase defaults, so a field labelled **Vendor** reads as
**Supplier** if that is your workspace's term. Filter paths never change, so
integrations and saved views are unaffected by a rename.
Some record content is displayed but not filterable: free-text notes,
activity timelines, document previews, and AI-generated narrative summaries.
Those are documented with their module under
[Products](/products/vendor-intelligence).
Data exports carry their own column set, which overlaps with but is not
identical to this catalog. See [Export](/export).
## Using a field path
A filter path is stable and safe to hard-code. Send it to
`POST /v1/vendor/query` as a rule tree: `path` is the filter path split on its
dots, `op` is one of the field's operators, and `combiner` is `all` (AND) or
`any` (OR). This returns high-risk vendors whose next assessment is already due,
soonest first:
```json theme={null}
{
"filter": {
"combiner": "all",
"children": [
{
"rule_type": "field",
"path": ["inherent_risk_level_id"],
"op": "in",
"value": ["cbsclvl_2Nk8xQ", "cbsclvl_7Pd1zR"]
},
{
"rule_type": "field",
"path": ["next_assessment_date"],
"op": "lte",
"value": "2026-06-30T00:00:00Z"
}
]
},
"sort": [{ "path": ["next_assessment_date"], "direction": "asc" }],
"limit": 50,
"offset": 0
}
```
Groups nest, so a `children` entry can itself be a `combiner` group when you need
mixed AND/OR logic. A date value can be an ISO-8601 timestamp or a relative
duration such as `-P30D`.
The `/query` routes are the ones the dashboard uses. They accept a signed-in
user's session token, not an `ak_...` API key, and return
`{ "data": [...], "total_count": }`. `limit` defaults to `50` and can be
up to `500`. See [Conventions](/conventions) for authentication.
# Import API Reference
Source: https://docs.coverbase.com/import
Endpoint reference for submitting batches of records via the Coverbase Import API.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
## Import Report
`POST /v1/import/{slug}`
Submits a batch of records to the specified import report. Records are processed one at a time against the report's field mapping and upserted on `external_id`. The response lists what each record created or updated.
Three things commonly cause a `404` or `422` here:
* The path is **`/v1/import/{slug}`**: singular `import`, not `imports`. A request to `/v1/imports/...` returns a generic `404 Not Found`, and a slug with no import report returns `422` with `Invalid import slug`.
* The records must be **wrapped under `data`**: `{"data": [ { ... } ]}`. A bare record, or an empty list, returns `422`.
* The Import API requires a **service-account API key**. A dashboard session token is rejected with `401 Unauthorized role.` See [API keys](/api-reference/api-keys).
### Path parameters
The import report's slug, shown as the endpoint on the report's **Configure** tab.
### Request body
The request body is a JSON object with a `data` key containing an array of records (or a single record object). Each record is an object whose keys are the mapped field names defined in the report and whose values are the incoming field values.
Records to import. Each record must include all fields marked as Required in the report's mapping.
### Example request
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/import/vendor-custom-import" \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"data": [
{
"Name": "Acme Corporation",
"External Id": "vendor-123",
"Website": "https://acmecorp.com",
"Status": "active",
"Hq Location": "San Francisco, CA",
"Raw Irq Score": "85"
},
{
"Name": "Beta Services",
"External Id": "vendor-456",
"Website": "https://betaservices.io",
"Status": "onboarding"
}
]
}'
```
```python Python theme={null}
import os
import requests
API_KEY = os.getenv("COVERBASE_API_KEY", "")
BASE_URL = "https://api.coverbase.app"
slug = "vendor-custom-import"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
}
payload = {
"data": [
{
"Name": "Acme Corporation",
"External Id": "vendor-123",
"Website": "https://acmecorp.com",
"Status": "active",
"Hq Location": "San Francisco, CA",
"Raw Irq Score": "85",
},
{
"Name": "Beta Services",
"External Id": "vendor-456",
"Website": "https://betaservices.io",
"Status": "onboarding",
},
]
}
resp = requests.post(
f"{BASE_URL}/v1/import/{slug}",
headers=headers,
json=payload,
timeout=30,
)
if resp.status_code == 422:
detail = resp.json()["detail"]
print(detail["message"] if isinstance(detail, dict) else detail)
for error in (detail.get("errors", []) if isinstance(detail, dict) else []):
print(error["record_index"], error.get("field"), error["error"])
else:
resp.raise_for_status()
result = resp.json()
print(result["message"])
for record in result["records"]:
vendor = record["vendor"]
print(record["record_index"], vendor["id"], "created" if vendor["created"] else "updated")
```
### Example response
`200 OK` when every record succeeds:
```json theme={null}
{
"success": true,
"message": "Successfully imported 2 record(s)",
"records_created": 2,
"errors": null,
"records": [
{
"record_index": 0,
"vendor": { "id": "cbvndr_e448ba62882143f3ba0c140bb2e30162", "external_id": "vendor-123", "created": false, "warnings": [] },
"services": [],
"engagements": [],
"assessments": [],
"findings": []
},
{
"record_index": 1,
"vendor": { "id": "cbvndr_9f4a1c0d7b2e4e9f8c1d2b3a4e5f6071", "external_id": "vendor-456", "created": true, "warnings": [] },
"services": [],
"engagements": [],
"assessments": [],
"findings": []
}
]
}
```
### Response fields
`true` on a `200` response.
A summary, such as `Successfully imported 2 record(s)`.
Number of records processed successfully, whether they created or updated objects.
One entry per successful record: its `record_index` (position in `data`), and the objects it created or updated under `vendor`, `services`, `engagements`, `assessments`, and `findings`. Each object carries `id`, `external_id`, `created` (`true` for a new object, `false` for an update), and `warnings`, such as an owner email that matched no user and was skipped.
Warnings that did not fail a record, such as a custom field sent as `null`, which is not written. `null` when there are none.
### Errors
If any record fails, the response is `422`. Records that succeeded are still saved, so fix the failed records and resend them; because records upsert on `external_id`, resending the whole batch is also safe. The `detail` object carries:
A summary, such as `Imported 1 of 2 record(s) with 1 error(s)`.
Number of records that succeeded.
Number of records in the request.
One entry per failed record, with `record_index`, `error` (a readable message, for example `Record missing required field External Id`), `field` (the incoming field name at fault, when there is one), `base_object` (which object the field belongs to, in a report that imports several), and `created` (objects a multi-object record saved before it failed, or `null`).
The results for the records that succeeded, in the same shape as `records` above.
Other failures return `422` with a plain-string `detail`: a body that is not valid JSON or has no records (`Invalid JSON: ...`), or a slug with no import report (`Invalid import slug`).
Partial success is supported. Records that pass validation are imported even if other records in the same batch fail. The HTTP status is `200` only when every record succeeds.
Need help? Email [support@coverbase.ai](mailto:support@coverbase.ai).
# Import API Concepts
Source: https://docs.coverbase.com/import-api
Push vendor, service, engagement, assessment, and finding data into Coverbase from upstream systems of record.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Import API is the ingestion counterpart to the Export API. It allows secure, programmatic delivery of vendor, service, engagement, assessment, and finding data into Coverbase from upstream systems of record.
## What you can do
Mirror your ERP, procurement system, or internal CMDB into Coverbase so procurement and risk share one source of truth.
Bulk-load historical assessment data when cutting over from a legacy TPRM platform or spreadsheets.
Keep third-party service mappings current by piping data from engineering or architecture catalogs.
Connect intake forms, ticketing, and contract lifecycle tools into the Coverbase vendor graph without manual re-entry.
The API uses a RESTful design with a predictable URL structure and communicates entirely in JSON. All interactions are authenticated with an API key and encrypted in transit.
## Setup
The Import API requires you to first create an import report in the [dashboard](https://dashboard.coverbase.app/api): open **Configuration → Coverbase API**, switch to the **Import API** tab, and click **New Import Report**. The report defines what records create or update, the field mapping between your incoming payload and Coverbase fields, and the POST endpoint used to submit records. Its **Configure** tab shows the endpoint and a sample payload; its **Request history** tab lists every request that reached the endpoint, with the request and response bodies.
To configure the report, you pick one or more objects under **Import data into**. When you POST to the endpoint, the request body contains a JSON array of records under the `data` key, each using the field names you mapped. Calls must use an `ak_` API key.
## Base objects
Every object upserts on `external_id`, the stable identifier from your source system: a record whose `external_id` matches an existing object of that type updates it in place instead of creating a duplicate. Objects that belong to another object name their parent by its `external_id` (`vendor_external_id`, `assessment_external_id`, `service_external_id`), so import parents first. Any mapped field that is not a standard field is treated as a custom field, and that custom field must already exist in your workspace.
### Vendor
Imports create or update vendor records in the Coverbase vendor inventory. Each record must include `name` and `external_id`. The payload also supports `website`, `displayed_website`, `description`, `hq_location`, `status` (a status label), `use_case`, `products`, `tags` (a list of `{"key": ..., "value": ...}` objects), the raw inherent and residual risk scores (`raw_irq_score`, `raw_residual_risk_score`), `risk_domain_scores`, `next_assessment_date`, `last_assessment_date`, `security_contact_email`, `trust_center_url`, `contact_personnel`, and people by email (`relationship_owner_emails`, `risk_analyst_emails`, `watcher_emails`). An email that matches no user is skipped with a warning.
A vendor imported with a `last_assessment_date` and no `next_assessment_date` is put on your organization's reassessment cadence counted from that date.
**Example:** Syncing the full list of active suppliers from your ERP nightly so that Coverbase's vendor inventory reflects procurement's source of truth without manual entry.
### Assessment
Imports create or update assessment records linked to a vendor. Each record must include `external_id` and `vendor_external_id`. The payload also supports `name`, `assignee_email`, `products`, `risk_type`, `status` (a status label), the raw inherent and residual risk scores, `recommendation`, `approval_option` (an approval option label), an assessment plan (`assessment_plan_id` or `assessment_plan_name`, applied only when the assessment is created), and `service_external_id` to link one of the vendor's services.
**Example:** Migrating three years of completed SIG Lite and CAIQ assessments from a legacy GRC platform so that vendor history is preserved when customers cut over to Coverbase.
### Service
Imports create or update service records representing the specific third-party services a vendor provides. A single vendor can have multiple services, each with its own risk profile. Each record must include `external_id`, `name`, and `vendor_external_id`.
The payload also supports `description`, `status`, the raw inherent and residual risk scores, `risk_domain_scores`, `next_assessment_date`, `tags`, `contact_personnel`, `relationship_owner_emails`, and `watcher_emails`.
**Example:** Loading a service catalog that distinguishes "Acme Corp, Payments API" from "Acme Corp, Cloud Hosting" so that assessments and monitoring events are scoped to the specific service consumed rather than the vendor as a whole.
### Finding
Imports create or update findings. Each record must include `external_id`, `title`, and exactly one of `vendor_external_id` or `assessment_external_id`. The payload also supports `description`, `status`, `due_date`, `assignee_email`, `watcher_emails`, and `severity`, `urgency`, and `risk_level` as level names from your finding scales. An unknown level name is skipped with a warning.
### Engagement
Imports create or update engagements under a vendor. Each record must include `external_id`, `name`, and `vendor_external_id`. The payload also supports `description`, `status`, `start_date`, `end_date`, the raw inherent and residual risk scores, `risk_domain_scores`, `tags`, `contact_personnel`, `relationship_owner_emails` (with `relationship_owner_first_name` and `relationship_owner_last_name` for a single owner), and `service_external_ids`, which replaces the engagement's service links. An unknown service `external_id` rejects the record.
### Several objects in one record
Select more than one object under **Import data into** to make a composite report. Each record then carries one key per object (`vendor`, `service` or `services`, `engagement` or `engagements`, `assessment` or `assessments`, `finding` or `findings`), each mapped separately, so one record can create a vendor together with its services, engagements, assessments, and findings. The objects in a record are saved one by one: if a later object fails, the ones before it stay saved and the error lists them.
## Field mapping
Each import report defines a mapping from incoming field names in your payload to the corresponding Coverbase fields on the object. The dashboard exposes all available target fields for the selected objects and marks which ones are **Required**.
Fields in a record that the mapping does not name are ignored. A record missing a required field is rejected, and the response lists it with the field that was missing.
Changing the mapping takes effect on the next request, without changing the endpoint URL or your client code.
## Request format
All requests are POST to the report endpoint with a JSON body of the shape:
```json theme={null}
{
"data": [
{ "Name": "Acme Corporation", "External Id": "vendor-123" },
{ "Name": "Beta Services", "External Id": "vendor-456" }
]
}
```
A single record can also be sent as an object under `data`. Records are processed one at a time, and each record that succeeds is saved even when another record in the same request fails. Because every object upserts on `external_id`, resending a request is safe. See the [Import API reference](/import) for the response.
# Coverbase documentation
Source: https://docs.coverbase.com/index
Guides for using the Coverbase third-party risk and procurement platform, and the API, integration and MCP reference for building on it.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase is a third-party risk and procurement platform. These docs cover both sides of it: using the product, and building against it.
Screen-by-screen guides for setting up Coverbase and running it day to day. Start here if you have the product open in another tab.
Authentication, the REST API, import and export, webhooks, workflows and the MCP server. Start here if you are moving data in or out.
Compliance posture, identity and access, data protection, regulatory alignment, service levels and contract terms. Start here if you are reviewing Coverbase as a vendor.
## If you are new to Coverbase
Three guides cover most people. Read the one that matches your job, then use the [user guides directory](/user-guides/overview) to find the rest.
Import vendors, build the intake questionnaire, tune scales and control sets, then set roles, templates and monitoring.
Triage requests, launch assessments, review what the AI found, follow up with vendors, and close the loop.
The short one. What you will be asked, how to file the request, and what happens next.
## Guides by area
The user guides follow the left navigation in the product, so the group a screen sits in is the group its guide sits in.
The vendor record, services and engagements, subprocessors, supplier bank and tax details with a country reference, and the centralized supplier portal.
The Intake Agent, Front Door triage, risk methodology, due diligence, claim check, the acceptance chain, the engagement record, clause packs, monitoring plans, offboarding, certificates, integrations, data share, Program Insights and the Agent Ledger.
The full assessment walkthrough, the quick reference, questionnaires, the IRQ library, evidence quality, and Zero Touch.
What happens after an issue becomes a finding, vendor commitments, and the obligations your organization takes on.
Registrations, people, financial health, security rating and sanctions screening, all assembled without contacting the vendor.
Working Radar signals, feeding in a Black Kite portfolio, vendor bills of materials, breach notification filings, the risk register, and the supplier geography map.
The contracts workspace, intake and approval, the repository, clause review with Contract Guardian, negotiation rounds, and signing.
Document Insights, asking your documents a question, and expiry reminders.
Ready-to-run workflow templates, building your own, the dashboard library, and Word report templates.
Running an RFP end to end, and inspecting your own applications with Inspect.
## Building on Coverbase
Three integration surfaces. Each works on its own, and you can combine them.
Pull vendor, assessment and control data out of Coverbase into your dashboards, BI tools and remediation workflows.
Push vendor, assessment and service data in from your ERP, CMDB, legacy GRC platform or service catalog.
Connect Claude, Cursor or any MCP client and work with your TPRM program through conversation.
Ask a Coverbase admin in your organization to provision one. See [API keys](/api-reference/api-keys).
Keep it in a secrets manager. Never commit a key to source control or embed it in client-side code.
Call `/v1/utils/authtest` with your bearer token to check connectivity, key validity and firewall rules before wiring anything up. The [authentication page](/quickstart) has the request.
Then jump to the reference for the endpoints you need. The [API conventions](/conventions) page covers IDs, timestamps, idempotency, pagination and the error envelope shared by every endpoint.
`https://api.coverbase.app`
REST, JSON over HTTPS, encrypted in transit.
## If you are evaluating Coverbase
The answers a third-party risk team, a procurement team or an examiner asks for, each on its own page.
How the platform maps to the 2023 Interagency Guidance on Third-Party Relationships, the Interagency Guidelines Establishing Information Security Standards, FFIEC, GLBA, DORA and NCUA.
Configurable gate outcomes, parallel domain-scoped SME reviews, multi-approver and threshold logic, and rework loops with reasons, comments and round counts.
SAML 2.0 SSO inheriting your IdP's MFA and conditional access, just-in-time provisioning, IGA-driven lifecycle, RBAC and network restriction.
The P0 to P3 severity ladder with response clocks, the timed escalation path, and the 99.9% uptime commitment.
Incident notification, data return and destruction, renewal and notice, subprocessors, and the diligence package.
Producing the complete due-diligence file for one third party, and assembling an examination package.
## What else is here
A page per capability, from Autonomous Intake to internal controls monitoring, grouped by area under **Get started**.
Every packaged control set: the vendor frameworks to assess a third party against, and the internal sets Inspect evaluates.
Every filterable field, its path, and where it comes from. The same paths drive saved views, workflow conditions and the query API.
Platform-specific guides for ServiceNow, Jira, Slack, OneTrust, DocuSign and more.
## Need help?
[support@coverbase.ai](mailto:support@coverbase.ai)
[security@coverbase.ai](mailto:security@coverbase.ai)
Talk to our team about your rollout or your integration.
# Integration directory
Source: https://docs.coverbase.com/integrations/directory
The external systems Coverbase connects with, organized by category, from cybersecurity ratings and GRC platforms to AI governance and procurement.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase connects with the tools your security, risk, and procurement teams already run. This directory lists the external systems available on the **Configuration → External Integrations** page in the dashboard, grouped by category. Some integrations are self-serve (you configure them yourself with an API key or credentials), while others are enabled by the Coverbase team during onboarding.
This directory reflects the integration catalog in the dashboard. For how integrations behave end to end (inbound API, workflow engine, and outbound webhooks), see [Integration Workflows](/integrations/overview). Platforms with a deep-dive guide (architecture diagrams, data mapping, trigger model) are linked below; see the [platform-specific guides](/integrations/guides/processunity). To connect a system not listed here, [talk to your Coverbase team](https://www.coverbase.com/contact).
## How to read this directory
* **A linked name** has a built-in connector with its own guide, or is read by a documented Coverbase feature (the link says which).
* **A name without a link** is listed in the dashboard catalog, but Coverbase has no built-in connector for it today. Its card on **Configuration → External Integrations** explains that Coverbase can build the integration and how to reach your Coverbase representative. It does not connect anything. [Talk to your Coverbase team](https://www.coverbase.com/contact), or connect it yourself through the [public API and webhooks](/integrations/guides/integration-platforms).
* Coupa, SAP Ariba, Ironclad, Icertis, Archer, ServiceNow IRM, the ERM risk register, Microsoft Teams, Bitsight, SecurityScorecard, Rapid Ratings, Moody's Analytics, ISNetworld, Avetta, EcoVadis, and the Snowflake, Amazon S3 and BigQuery destinations are part of the third-party lifecycle features, which your Coverbase representative turns on for your organization.
## Cybersecurity & threat intelligence
Outside-in security ratings, attack-surface, and threat-intelligence sources that enrich Vendor Intelligence.
[Shodan](/user-guides/security-intelligence), [Censys](/user-guides/security-intelligence), [Have I Been Pwned](/user-guides/dark-web-monitoring), Axio, [Bitsight](/integrations/guides/bitsight), [Black Kite](/user-guides/black-kite-monitoring), CyberGRX, Panorays, Recorded Future, RiskRecon, [SecurityScorecard](/integrations/guides/securityscorecard), UpGuard, Mandiant, IONIX, Cyberhaven.
## AI Governance & Safety
AI governance, AI security, and model-risk platforms for evaluating vendors that build or depend on AI systems, a natural companion to the [AIUC-1, ISO/IEC 42001, EU AI Act, OWASP LLM, and MITRE ATLAS control sets](/control-library#ai-governance).
Credo AI, Holistic AI, FairNow, Lakera, Robust Intelligence, HiddenLayer, Protect AI, Cranium, Lasso Security, WitnessAI.
## SaaS Security Posture Management (SSPM)
Identity, configuration, and posture signals from your SaaS estate.
[Okta](/user-guides/internal-controls-monitoring), FalconShield (Adaptive Shield), AppOmni, Grip Security, Obsidian Security, Valence Security (configured on its card), Nudge Security.
## Identity & single sign-on (SSO)
Identity providers Coverbase reads users, application assignments, and access data from.
[Microsoft Entra ID](/user-guides/internal-controls-monitoring), Google Workspace, AWS IAM Identity Center, OneLogin, Ping Identity, JumpCloud, Cisco Duo, Auth0, CyberArk, SailPoint, Saviynt. Okta is listed under SaaS Security Posture Management above.
These are the identity systems Coverbase **reads from**, for access reviews and application inspection. Signing **in to** Coverbase is a separate capability: SAML 2.0 enterprise SSO, which inherits your identity provider's MFA and conditional-access policy, with just-in-time provisioning and an API for IGA-driven joiner/mover/leaver lifecycle. See [Identity and access management](/security/identity-and-access).
## HR & workforce management (HRIS)
HR and payroll systems that supply employee, contractor, and org data for ownership and access reviews.
Workday, BambooHR, ADP, UKG, Rippling, Gusto, Paychex, Paycom, Namely, SAP SuccessFactors, Oracle HCM Cloud, Dayforce, HiBob, Deel.
## GRC & risk management platforms
Governance, risk, compliance, and third-party risk management systems Coverbase exchanges data with. Coverbase also runs the internal side of enterprise risk natively: see [Internal control monitoring](/products/internal-controls-monitoring) for evaluating the controls inside your own applications on the same control model, risk domains, scales, findings and dashboards as your third-party program.
[Archer](/integrations/guides/archer), AuditBoard, Diligent, Fusion Risk Management, LogicGate, LogicManager, MetricStream, NAVEX Global, [OneTrust](/integrations/guides/onetrust), Prevalent, [ProcessUnity](/integrations/guides/processunity), Riskonnect, Resolver, SAI360, [ServiceNow GRC](/integrations/guides/servicenow), Vendor Insight, Vendor Risk, Venminder, Workiva, [Aravo](/integrations/guides/aravo), Whistic, VISO TRUST, Certa, Graphite Connect, Supply Wisdom, Ncontracts.
[Archer](/integrations/guides/archer) and [ServiceNow IRM](/integrations/guides/servicenow-irm) receive findings as issues and vendors as risks, and a REST risk register can receive vendor risk through the [ERM risk register](/integrations/guides/erm-register) connector, all through the Integration Hub. The [ServiceNow integration](/integrations/guides/servicenow) covers ServiceNow VRM and ITSM records from workflows.
## Compliance Automation & Trust Management
Continuous-compliance and trust-management platforms that automate control monitoring and evidence collection.
Vanta, Drata, Secureframe, Thoropass, Hyperproof, Sprinto, Conveyor, Vendict. [SafeBase](/integrations/guides/safebase) trust centers are read automatically during vendor enrichment, so SafeBase has no card on the page.
## Financial crime & AML
Anti-money laundering, fraud, and financial-crime platforms that risk teams at banks, credit unions, and fintechs run alongside Coverbase.
NICE Actimize, Nasdaq Verafin, Oracle Financial Crime and Compliance Management, SAS Anti-Money Laundering, Quantexa, Feedzai, Featurespace, Fenergo, Unit21, Hummingbird, Sardine, Alloy, Napier AI, Silent Eight, Chainalysis.
## Privacy & data governance
Data discovery, consent, and data-subject-request platforms that govern the personal data your vendors process.
Securiti, BigID, Transcend.
## Document & contract lifecycle management
Contract and document systems Coverbase reads obligations from and writes back to.
Adobe Acrobat Sign, Agiloft, CobbleStone, Concord, Conga, ContractPodAi, [DocuSign](/integrations/guides/docusign), Dropbox Sign, Evisort, Gatekeeper, Harvey, [Icertis](/integrations/guides/icertis), [Ironclad](/integrations/guides/ironclad), Juro, LinkSquares, Luminance, Malbek, Onit, SirionLabs, SpotDraft.
The [DocuSign integration](/integrations/guides/docusign) initiates execution from a Coverbase document, routes countersignature through ordered signer slots, tracks envelope status on the record, and keeps the executed agreement attached to the third party it belongs to.
## Procurement & supplier management
Procurement, sourcing, and supplier-management platforms that drive vendor onboarding and spend.
[SAP Ariba](/integrations/guides/sap-ariba), [Coupa](/integrations/guides/coupa), [Workday Strategic Sourcing](/integrations/guides/workday-strategic-sourcing), GEP SMART, Ivalua, Jaggaer, Levelpath, Lio, NetSuite, Omnea, ORO Labs, Zip, Tropic, Vendr, Sastrify.
## Supply chain & nth-party risk
Multi-tier supplier mapping, disruption sensing, and ownership intelligence for risk that sits beyond your direct vendors.
Interos, Exiger, Resilinc, Everstream Analytics, Sayari.
## IT service management
Ticketing and service-management systems for routing findings and tasks.
Freshservice, [Jira](/integrations/guides/jira), [ServiceNow ITSM](/integrations/guides/servicenow).
## Communication & collaboration
Messaging workspaces Coverbase connects to.
[Slack](/integrations/guides/slack), [Microsoft Teams](/integrations/guides/microsoft-teams).
## Sustainability & ESG
ESG ratings and sustainability-risk sources.
CyberVadis, [EcoVadis](/integrations/guides/ecovadis), ISS ESG, Sustainalytics.
## Financial & business data
Company, credit, and ownership data that enriches vendor records and Vendor Intelligence.
Bureau van Dijk (Orbis), [Crunchbase](/products/financial-health-score), [Dun & Bradstreet](/products/vendor-intelligence), [Moody's Analytics](/integrations/guides/moodys), [PitchBook](/products/financial-health-score), [Rapid Ratings](/integrations/guides/rapidratings), S\&P Global.
## Regulatory & compliance data
Sanctions, enforcement, and public-registry sources used for screening and due diligence.
[CFPB enforcement actions](/products/source-library), ComplyAdvantage, Dow Jones Risk & Compliance, [FDIC](/products/source-library), [FinCEN enforcement actions](/products/source-library), GBG, [OFAC](/user-guides/sanctions-screening), [OpenCorporates](/products/corporate-registrations), [SEC EDGAR](/user-guides/breach-notification-monitoring).
## Risk intelligence & analytics
Screening, adverse-media, and identity-verification data for third-party due diligence.
Bitsight Security Scorecard, Kroll, [LexisNexis](/products/source-library), [LSEG (Refinitiv World-Check)](/products/source-library), [Refinitiv World-Check](/products/source-library), Trulioo, UpGuard, RiskRecon by Mastercard.
## Tax & VAT validation
Registries Coverbase validates vendor tax and VAT identifiers against.
SAP, Sovos (Convey), [VIES](/user-guides/supplier-information).
## Contractor prequalification
Contractor safety, insurance and compliance networks that feed the [Certificate Vault](/products/certificate-vault). These appear on the page once your organization has the third-party lifecycle features.
[ISNetworld](/integrations/guides/isnetworld), [Avetta](/integrations/guides/avetta).
## Data warehouses
Destinations for [warehouse data share](/products/warehouse-data-share), configured on **Configuration → Data Share** rather than on the External Integrations page.
[Snowflake](/integrations/guides/snowflake), [Amazon S3](/integrations/guides/amazon-s3), [BigQuery](/integrations/guides/bigquery).
## Integration platforms and API access
Workato, MuleSoft and Boomi connect through Coverbase's starting points (a Workato custom connector, a Mule 4 template and a Boomi recipe) built on [OAuth 2.0 client credentials](/integrations/guides/oauth-client-credentials), the REST API and signed webhooks. They are templates rather than certified marketplace connectors: see [Integration platforms](/integrations/guides/integration-platforms).
## Related
How inbound API, the workflow engine, and outbound webhooks fit together.
What Coverbase configures during onboarding, and reference architectures.
Subscribe downstream systems to Coverbase events.
Connect Coverbase to AI assistants and connectors via the MCP server.
# End-to-end workflows
Source: https://docs.coverbase.com/integrations/end-to-end-workflows
Three full lifecycle walkthroughs showing every API and webhook touchpoint.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The walkthroughs below trace three full lifecycle workflows. Each is built from the same no-code triggers, conditions and actions any admin composes in the **Workflows** section of the dashboard, so treat them as worked examples to copy and edit rather than as fixed templates. Event names are real catalog values. For the authoritative, case-sensitive list of subscribable events and the exact API request/response schemas, always defer to the [event catalog](/integrations/webhooks#event-catalog) and the [API reference](/api-reference/assessments).
## Workflow A: Vendor onboarding
A new third-party request enters Coverbase from procurement, gets risk-classified, drives the appropriate assessment depth, and produces a decision artifact that flows back to procurement and contract management.
Source system: Ariba, or any procurement intake.
```http theme={null}
POST /v1/import/vendor-intake
```
```json theme={null}
{
"data": [{
"Name": "Acme Corporation",
"External Id": "ariba-req-7821",
"Website": "https://acmecorp.com",
"Status": "intake",
"Business Unit": "Engineering",
"Requested Use": "Customer support ticketing",
"Data Types": ["customer_pii"]
}]
}
```
**Trigger fired:** `Vendor.Created`.
The workflow inspects `Data Types`, `Requested Use`, and `Business Unit`. Conditions branch:
* If `customer_pii` is present and the vendor has SaaS hosting, route to the full security and privacy assessment path.
* If the engagement is a commodity, with no data access and no system integration, route to a lightweight financial and compliance check and skip directly to procurement approval.
Amount is a branch too: a contract-value condition compares the total value of the contracts on the procurement against your delegation-of-authority threshold, so a request above the limit picks up the extra approver and one below it does not.
This is a configured branch. The configuration itself is API-readable and API-modifiable.
**Action:** create assessment, send a portal with the questionnaire to the vendor contact.
**Webhook fired:** `Assessment.Created`, carrying the `assessment_id`. Your GRC tool receives the webhook and creates a corresponding tracking record.
Vendor uploads SOC 2 and completes the questionnaire through the vendor portal.
**Webhook fired:** `QuestionnaireResponse.Updated` as the response moves through its statuses, and `VendorDocument.Created` for each uploaded document.
Copilot runs as part of the assessment, not as a separate workflow action. It extracts control evidence from the SOC 2 and reconciles it against questionnaire responses. Evaluations are produced for each control.
**Webhook fired:** `Assessment.Updated`, with the status change in `field_diffs`, as the assessment moves toward completion.
**Action:** issues found in the evaluations are raised as findings. For findings above a configured severity, a workflow on `Finding.Created` creates a work queue item for the internal risk owner.
**Webhook fired:** `Finding.Created`, one per finding. Your Jira instance receives webhooks and creates tickets, or the workflow's **Create jira ticket** action creates them directly.
**Action:** create one review per implicated risk domain, each scoped to that domain and routed to its standing reviewers, individually or as a user group. InfoSec, Financial Crime, Legal, Privacy and Finance receive their own work queue item and see the slice of the evidence they own.
Each review carries its own assignee, status, notes and outcome, and they complete in whatever order the SMEs complete them. One domain returning its scope for rework does not reopen another domain's decision.
**Webhook fired:** `WorkQueueItem.Created`, one per domain review, so your ITSM or GRC platform can mirror the queue.
**Condition:** a work-queue-item-complete condition scoped to the workflow run, with `require all` set, holds the next step until every domain review is decided. Set `require all` off for a first-past-the-post gate, and raise a different set of reviews per tier to express a quorum.
Each reviewer selects an outcome from your organization's own list: **Approve**, **Approve with finding**, **Approve with policy exception**, **Reject**, or **Return for rework**. The selected outcome is a branch point: an assessment-recommendation condition routes a policy exception down a different path from a clean approval, raising the exception record and scheduling an earlier reassessment.
**Webhook fired:** `Review.Updated` and `WorkQueueItem.Completed` per decision, then `Assessment.Updated` and `Vendor.Updated`, each with the status change in `field_diffs`, once the gate clears. The Ariba integration receives `Vendor.Updated` and unblocks the procurement record. Contract management receives the same event and starts contract drafting with risk context attached.
Where a reviewer selects **Return for rework**, the round is returned with a revision message rather than closed. The round number increments, the previous round is preserved rather than overwritten, and the item reappears as outstanding work for whoever owes it: the vendor in their portal, or the requester in intake.
Every loop is countable. Rounds are rows, so "how many cycles did this assessment take", "which control areas generate the most rework" and "how long did each side hold each round" are queries rather than reconstructions. See [Reviews, approvals and gates](/user-guides/reviews-and-approvals#return-for-rework).
When the draft MSA is uploaded, either via UI, API, or pulled from your CLM through a separate integration, Contract Guardian runs automatically. Missing clauses, liability deviations, and AI usage provisions are surfaced.
**Webhook fired:** `Contract.Created` when the agreement lands, and `Contract.Updated` as its fields change. There is no separate event for the clause review finishing, so your receiving handler routes the new contract to the legal team.
## Workflow B: Ongoing monitoring and reassessment
After a vendor is active, Coverbase runs continuous monitoring and triggers reassessment work when conditions warrant.
### Continuous monitoring with Supplier Radar
Supplier Radar ingests external signals such as breaches, sanctions, regulatory actions, and threat intelligence, and produces events scoped to specific vendors. When an event lands above a configured severity threshold:
* **Trigger fired:** `RadarSignal.Created`, with `RadarDetectorResult.Created` for each alert a detector raises.
* Conditions branch on the signal's fields and the vendor's tier.
* For high-severity events on tier 1 vendors, action: create a targeted incident assessment, create a work queue item for the risk owner, and send a webhook to your paging tool.
**Webhook fired:** the **Send webhook** action delivers the triggering signal event to the webhooks it names.
### Scheduled reassessment
Reassessment rules set each vendor's next assessment date from its risk level, for example quarterly for the highest level and annually below it. There is no recurring workflow trigger, so when an external GRC tool owns the cadence, it starts the assessment itself:
```http theme={null}
POST /v1/assessments
```
```json theme={null}
{
"vendor_id": "cbvndr_...",
"control_set_ids": ["cbctst_..."],
"trigger_workflow": "scheduled-reassessment-flow"
}
```
### Contract renewal trigger
There is no renewal-window trigger. Notice and renewal dates are tracked as [contract dates and reminders](/user-guides/contract-dates-and-reminders), and `Contract.Expired` fires when a contract's term runs out.
**Trigger fired:** `Contract.Expired`. The workflow optionally launches a reassessment and sends a webhook to your CLM with current risk context.
## Workflow C: Vendor offboarding
When a relationship ends, Coverbase coordinates the offboarding sequence.
```http theme={null}
PATCH /v1/vendors/cbvndr_e448ba62882143f3ba0c140bb2e30162
```
```json theme={null}
{
"status_id": "cbsts_offboarding_7f8e9d0c"
}
```
**Trigger fired:** `Vendor.Updated`, with the status change in `field_diffs`.
**Action:** create a termination assessment focused on data return, access revocation, and exit obligations from the contract. **Action:** send a portal with a structured offboarding questionnaire covering data destruction certification, access termination confirmation, and return of materials.
**Webhook fired:** `Assessment.Created`.
**Action:** **Send webhook** to your IAM tool's endpoint. It receives the event and revokes vendor user accounts, API keys, and SSO entitlements.
Documents stay on the vendor record after offboarding. If your records policy needs a copy in long-term storage, your webhook handler pulls them through the [Documents API](/api-reference/documents).
When all offboarding tasks complete, an **Update vendor status** action moves the vendor to your offboarded status.
**Webhook fired:** `Vendor.Updated`. Procurement and finance systems receive the event and close their respective records.
These scenarios use the generic surfaces. For the named platforms Coverbase integrates with natively (ProcessUnity, ServiceNow VRM, OneTrust, Workday Strategic Sourcing, Aravo), see the [platform-specific guides](/integrations/guides/processunity), which show how each one composes these same flows.
## Reference diagram
```
External Systems
─────────────────────────────────────────────────────────────────
Ariba · Icertis · ServiceNow · Jira · Slack · IAM · CLM · Warehouse
▼ Inbound API Webhooks ▲
Coverbase API
─────────────────────────────────────────────────────────────────
POST /v1/import/{slug} Vendors, Assessments, Services
POST /v1/vendors Create vendor
POST /v1/assessments Start assessment
POST /v1/workflows/{name}/run Invoke named workflow
PATCH /v1/vendors/{id} Lifecycle transitions
POST /v1/webhooks Register outbound endpoints
▼
Workflow Engine
─────────────────────────────────────────────────────────────────
Triggers ▶ Conditions ▶ Actions
Object events IRQ score Create assessment
Scheduled runs Field filters Send portal
External calls Tier Raise review gate (per domain)
Contract value Create work queue item
Approval outcome Update status
Reviews complete Send webhook
Field changes Jira / ServiceNow record
▼
Primary Object Store
─────────────────────────────────────────────────────────────────
vendor · service · engagement · assessment · evaluation
document · contract · entity · control · control_set
review · risk_domain · finding · obligation · work_queue_item
Vendors, services, documents, assessments,
findings and obligations also via the public API
```
# Amazon S3
Source: https://docs.coverbase.com/integrations/guides/amazon-s3
Share your third-party risk tables into your own S3 bucket on a schedule as CSV, JSON Lines or Parquet, written by a role in your account that Coverbase assumes with an external ID.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
An Amazon S3 destination is part of [warehouse data share](/products/warehouse-data-share). Coverbase stores no secret for it. It assumes an IAM role in your account, using an external ID generated for that one destination, and writes files under the prefix you choose.
## How access works
```mermaid theme={null}
sequenceDiagram
participant CB as Coverbase share role
participant STS as AWS STS
participant Role as Your IAM role
participant S3 as Your bucket
CB->>STS: AssumeRole(your role, external ID)
STS->>Role: Trust policy: principal and external ID match?
STS-->>CB: Short-lived credentials
CB->>S3: PutObject under your prefix
```
* **One principal.** Your role trusts a single, dedicated Coverbase role that exists only to assume customer share roles. The destination card shows it under **AWS principals your role must trust**. Coverbase's services reach your role only through it.
* **One external ID per destination.** It is generated when you save the destination, starts with `coverbase-`, and is shown on the card. Coverbase's share role may only assume a role that demands a `coverbase-` external ID and sits outside Coverbase's own AWS account, and yours demands this destination's, so your role cannot be used for another customer's destination. A role ARN in Coverbase's own account is refused when you save.
## Prepare the bucket and role
1. Choose a bucket and a prefix for Coverbase's files.
2. Create an IAM role with a policy that allows `s3:PutObject` under that prefix, for example:
```json theme={null}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::your-bucket/coverbase/*"
}
]
}
```
You finish the role's trust policy after saving the destination in Coverbase, when the external ID exists.
## Add the destination in Coverbase
1. Open **Configuration → Data Share** and click **Add destination**.
2. Choose **Amazon S3**, give it a **Name**, and choose **Hourly** or **Daily**.
3. Enter the **Bucket**, **Prefix**, **Region** and **IAM Role ARN**, and choose the **File Format**: **CSV (gzip)**, **JSON Lines (gzip)** or **Parquet (snappy)**.
4. Click **Add destination**.
5. On the destination card, click **Copy trust policy** and set it as your role's trust policy. It has this shape, with the principal and external ID filled in:
```json theme={null}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "AWS": "" },
"Action": "sts:AssumeRole",
"Condition": { "StringEquals": { "sts:ExternalId": "coverbase-" } }
}
]
}
```
6. Click **Test connection**, then **Sync now**.
## What lands in the bucket
* Files at `/
/synced_date=YYYY-MM-DD/-.`, in the format you chose.
* Each table's contract at `/_contract/
.json`.
* Each sync appends the rows that changed, stamped with `_cb_synced_at`. Deduplicate on `id`, keeping the latest `_cb_synced_at`. The `services` table is a full snapshot on every run.
## Related
Run logs, pausing and the table contract.
Why the external ID matters.
The Snowflake destination.
The BigQuery destination.
# Aravo
Source: https://docs.coverbase.com/integrations/guides/aravo
Coverbase as the risk-triage and intelligence layer alongside Aravo: bulk vendor populations triaged by AI, high-risk vendors routed into Aravo workflows, risk data synced back.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase deploys alongside **Aravo** as the risk-triage and intelligence layer: Coverbase absorbs the vendor population, assesses and scores it with AI, and routes each vendor to the right treatment (Aravo's workflows for the vendors that warrant them, continuous monitoring for the middle of the book, full assessments where depth is needed), while keeping Aravo's supplier records current with the latest risk data. Your Aravo investment keeps doing what it does well; Coverbase answers the question Aravo can't: *which of these thousands of vendors deserve the workflow?*
This architecture runs on Coverbase's shipped integration surfaces (the [Import API](/import-api), [Zero Touch Assessments](/products/zero-touch-assessments), [Supplier Radar](/products/supplier-radar), the [workflow engine](/integrations/workflow-engine), and the [Export API](/export-api-concepts)), configured to your Aravo tenant during onboarding.
```mermaid theme={null}
flowchart LR
subgraph aravo["Aravo (system of record)"]
pop["Supplier population"]
wf["Aravo workflows"]
rec["Supplier records"]
end
subgraph cb["Coverbase"]
imp["Import API (bulk)"]
triage["Passive assessment & risk scoring"]
route{"Risk routing"}
radar["Supplier Radar (continuous monitoring)"]
full["Full assessments"]
exp["Risk data sync"]
end
pop -->|bulk import| imp --> triage --> route
route -->|high risk| wf
route -->|medium risk| radar
route -->|depth needed| full
radar --> exp
full --> exp
triage --> exp
exp -->|scores · tiers · outcomes| rec
```
## The two tracks
**Track 1: triage the existing population.** Most Aravo estates carry a large vendor population with no current risk assessment. The full population bulk-imports into Coverbase, where passive assessments and AI risk scoring triage every vendor without sending anyone a questionnaire. The output is a tiered book: high-risk vendors route into Aravo's workflows with their risk context attached, medium-risk vendors go under Supplier Radar's continuous monitoring, and the vendors that need real depth get full Coverbase assessments.
**Track 2: steady state.** New vendors enter through [Autonomous Intake](/products/autonomous-intake) and flow through the same scoring and routing automatically, so the triage never goes stale. Score changes (a monitoring alert, a completed assessment, a reassessment) sync back to the Aravo supplier record.
## Trigger model
```mermaid theme={null}
sequenceDiagram
participant AR as Aravo
participant CB as Coverbase
Note over AR,CB: Track 1 - initial triage
AR->>CB: Bulk import supplier population
CB->>CB: Passive assessment + AI risk scoring (no vendor outreach)
CB->>AR: High-risk vendors → Aravo workflows, with risk context
CB->>CB: Medium risk → Supplier Radar · depth needed → full assessment
Note over AR,CB: Track 2 - steady state
CB->>CB: New vendor via Autonomous Intake → same scoring and routing
CB->>AR: Sync score changes and assessment outcomes to supplier records
```
## Why triage-first works
* **No outreach cost for the long tail.** Passive assessment scores vendors from external signals and existing evidence. The majority of a large population is tiered without a single questionnaire sent.
* **Aravo gets fewer, better-qualified cases.** Its workflows receive the vendors that warrant them, each arriving with its risk score, tier, and the evidence behind them.
* **Nothing falls out of view.** The middle of the book isn't parked: Supplier Radar watches it continuously, and a deteriorating vendor is promoted into a real review automatically through the workflow engine.
* **The record of record stays current.** Risk data flows back to Aravo on every change, keyed on Aravo's supplier identifiers, so downstream Aravo reporting reflects live risk rather than the last manual review.
## Authentication and provisioning
The bulk import and steady-state pushes authenticate with an org-scoped Coverbase service-account API key. The sync back to Aravo is configured against your Aravo tenant's API during onboarding, with credentials held in Coverbase's secrets manager.
## Onboarding checklist
1. A supplier extract from Aravo (or API access) for the initial bulk import, Aravo supplier IDs included, so every record round-trips.
2. Your risk-tier thresholds: which scores route to Aravo workflows, monitoring, or full assessment.
3. Aravo API credentials for the risk-data sync back to supplier records.
4. The intake path for new vendors (Autonomous Intake, or a push from your procurement stack as described in [integration patterns](/integrations/patterns)).
# Archer
Source: https://docs.coverbase.com/integrations/guides/archer
Push Coverbase findings as issues and vendors as risks into RSA Archer content records, and read each record's status back, through the Integration Hub.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Archer connector is part of the [Integration Hub](/products/integration-hub). It writes Coverbase findings and vendor risk into Archer content records in the applications you name, and reads back a status field after each sync, so your Archer program sees third-party risk without re-keying it.
## What it pushes
* **Findings as issues**: every open finding that has a vendor, plus every finding already pushed, so a closure reaches Archer too.
* **Vendor risk**: every vendor with a residual or inherent risk level, plus every vendor already pushed.
Each record is created the first time and updated after that, and only when one of its mapped values changed. Coverbase keeps a link from each Coverbase record to the Archer record, which the sync log shows.
| Coverbase value | Issues (findings) | Risks (vendors) |
| - | - | - |
| **Title** | The finding's title | The vendor's name followed by "third party risk" |
| **Description** | The finding's text | |
| **Severity** | The finding's severity level | |
| **Status** | The finding's status | |
| **Vendor** | The vendor's name | The vendor's name |
| **Due date** | The remediation due date | |
| **Residual risk**, **Inherent risk**, **Risk tier**, **Approval status** | | The vendor's levels and status |
| **Open findings** | | How many open findings the vendor has |
| **Coverbase reference** | The finding number | The vendor's Coverbase ID |
| **Coverbase link** | A link to the finding | A link to the vendor |
Every value is written as text. A value with a blank target is not written.
## Status read back
After each push, Coverbase reads the status field you named on every record it holds, a text or values list field, and shows it on the record link. It does not change the finding in Coverbase.
## Authentication
Archer uses a service account. Coverbase signs in at `/api/core/security/login`, holds the session only for the sync, and sends it as `Authorization: Archer session-id=`.
1. Create an Archer service account with rights to create and update content in the issue and risk applications.
2. Note the application level ID that holds issue records, the one that holds risk records, and the field ID of the status field in each.
3. Note the field ID of each Archer field you want each Coverbase value written to.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **Archer**, or open it from the **GRC and ERM** category of the Integration Hub.
2. On **Authentication**, enter the **Instance URL** (the https\:// address you sign in to Archer at), the **Instance Name**, the **User Domain** (blank for a local Archer account), and the **Service Account Username** and **Service Account Password**.
3. Under **Archer Application**, enter the **Issue Level ID** and **Issue Status Field ID**, the **Risk Level ID** and **Risk Status Field ID**, or both pairs.
4. Turn on **Push findings and vendor risk to Archer**, set the **Sync Interval (Minutes)**, click **Save**, then **Test connection**.
5. On **Field Mappings**, enter the Archer field ID for each value under **Findings as Issues** and **Vendor Risk**, and **Save mappings**.
6. Click **Sync now** and read the **Sync Log**.
## When a response is not what Coverbase expects
Coverbase checks every Archer response for its success flag. A reply that is not the documented shape fails that record, with the reason in the sync log, instead of being read as success.
If a create succeeds in the provider but Coverbase fails to save its link to the new record, the next sync creates a second record instead of updating the first. Remove any duplicate it leaves in the provider.
## Related
Field mappings and the sync log.
Building your own sync on the API instead.
The findings pushed as issues.
How the credentials are stored.
# Avetta
Source: https://docs.coverbase.com/integrations/guides/avetta
Sync Avetta supplier compliance status, safety statistics and insurance into the Certificate Vault daily, for prequalification rules to read.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Avetta connector feeds the [Certificate Vault](/products/certificate-vault). You bring your own Avetta subscription, and Coverbase reads it with your credentials once a day.
If a Avetta response does not have the shape Coverbase expects, the sync stops and records the error. It never treats such a response as an empty list, because an empty pull archives every certificate the network supplied.
## What it does
Avetta prequalifies suppliers and contractors on safety, insurance and compliance. Coverbase reads your client account's suppliers and writes each one's **Avetta prequalification** status, safety statistics and insurance into the vault.
* **Matched to your vendors.** Each record is matched to a vendor by a match recorded on an earlier run, then by its domain (walking up to the parent domain, never down), then by its exact legal name. A record that matches no vendor is skipped.
* **Kept current.** A network record is keyed by the network's ID and the certificate type. A complete pull archives records the network no longer returns.
* **Read by prequalification.** Network grade, network status and safety or ESG figure conditions in your [prequalification rule sets](/user-guides/certificate-vault#step-4-write-a-prequalification-rule-set) read these records. Only current records count.
## Authentication
Avetta issues an API token for your client account. Coverbase reads `/v1/clients//suppliers` from `https://api.avetta.com`.
1. Ask Avetta for an API token for your client account.
2. Note your Avetta client ID.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **Avetta**.
2. Enter **API Token** and **Account ID** (your client ID).
3. Click **Save**, then **Test connection**.
4. On the **Certificates** page, the **Networks** card shows Avetta as connected, with its certificate count and last sync. Click **Sync now** for the first pull.
If a sync fails, the panel and the **Networks** card show **The last sync failed** with the reason. Only Coverbase's own error messages are stored, never a credential or the provider's response. **Remove** deletes the stored credentials; certificates already pulled stay.
## Related
The vault, rule sets and overrides.
What prequalification does.
Prequalification on an intake request.
Every system Coverbase connects to.
# BigQuery
Source: https://docs.coverbase.com/integrations/guides/bigquery
Share your third-party risk tables into your own BigQuery dataset on a schedule, authenticated with a service account key, with a current view beside every table.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A BigQuery destination is part of [warehouse data share](/products/warehouse-data-share). Coverbase writes through the BigQuery REST API with a service account key, creates one table per contract table on the first sync, and keeps a `
_current` view beside each.
## Prepare BigQuery
1. Create a service account for Coverbase.
2. Grant it **BigQuery Data Editor** on the dataset and **BigQuery Job User** on the project.
3. Create a JSON key for the service account.
The dataset is created if it does not exist yet, in the location you give.
## Add the destination in Coverbase
1. Open **Configuration → Data Share** and click **Add destination**.
2. Choose **BigQuery**, give it a **Name**, and choose **Hourly** or **Daily**.
3. Enter the **Project ID**, **Dataset** and **Location**, and paste the **Service Account Key (JSON)**.
4. Click **Add destination**, then **Test connection**, then **Sync now**.
After saving, the card shows the service account's email as a hint. The key is never shown again. Archiving the destination deletes it.
## What lands in BigQuery
* One table per contract table, created on the first sync, with any column the contract adds later added to it.
* Each sync appends the rows that changed, stamped with `_cb_synced_at`.
* A `
_current` view per table keeps the newest version of each row.
Point Looker Studio, Power BI or Tableau at the `_current` views.
## Related
Run logs, pausing and the table contract.
The Snowflake destination.
The S3 destination.
How the key is stored.
# Bitsight
Source: https://docs.coverbase.com/integrations/guides/bitsight
Bring Bitsight security ratings for your portfolio into Coverbase: each vendor's rating is recorded, and a material drop becomes a Radar signal.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Bitsight connector is a licensed rating connector: you bring your own Bitsight subscription, and Coverbase reads your portfolio with your credentials. It works like the [Black Kite integration](/user-guides/black-kite-monitoring). Ratings land on the vendor's **Certificates** tab under **Licensed Ratings**, and changes become [Radar](/products/supplier-radar) signals.
## What it does
* **Provisions monitoring once.** The first time you save credentials, Coverbase adds one Bitsight source to Radar and one detector on it, named for a security rating drop. Both are created once. Archiving the source stops monitoring, and saving new credentials later does not bring it back.
* **Matches companies to vendors.** Each company in your portfolio is matched to a vendor by a match recorded on an earlier pull, then by its domain (walking up to the parent domain, never down), then by its exact legal name. A company that matches no vendor is skipped.
* **Records the rating.** Each pull records the matched vendor's Security Rating (250 to 900).
* **Signals only on change.** A Radar item is raised only when a stored rating moved. The first pull is a baseline, so connecting a provider does not flood Radar.
## The detector
The detector starts enabled, alerting on a drop of 30 points or more between pulls. Edit it like any other Radar detector. It has three gates, and at least one must be set. A rating change alerts only when it passes every gate that is set. **Minimum drop** and **Alert below** take zero or more, in the provider's own units.
| Gate | Passes when |
| - | - |
| Minimum drop | The rating fell by at least this much since the last pull. |
| Alert below | The rating is below this value. |
| Grade worsened | The provider's grade or band got worse. |
Alerts go through the ordinary Radar path, so reassessment triggers and monitoring plan signal rules see them like any other signal.
## Authentication
Bitsight issues an API token. Coverbase sends it as the HTTP Basic user name to the Ratings API v2 at `https://api.bitsighttech.com` and reads your portfolio from `/ratings/v2/portfolio`.
1. In Bitsight, create an API token for a user who can read your portfolio.
2. Add the vendors you want monitored to that portfolio.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **Bitsight**.
2. Enter **API Token**. The panel notes: "Saving the token adds a Bitsight source to Radar. Rating changes on matched vendors become signals."
3. Click **Save**, then **Test connection**.
4. Open **Radar** to find the new source and its detector.
The panel never shows a stored secret again. **Remove** deletes the stored credentials; ratings already pulled stay.
## Related
Where licensed ratings show on a vendor.
Triaging the signals a rating change raises.
Letting a rating drop pull monitoring forward.
Coverbase's own outside-in rating, which needs no subscription.
# Coupa
Source: https://docs.coverbase.com/integrations/guides/coupa
Two-way sync with Coupa through the Integration Hub: requisitions open intake requests, suppliers link to vendors with their approved supplier status, contracts and budget lines sync in, and Coverbase writes risk tier, approval status and contract risk back to Coupa custom fields.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Coupa connector is part of the [Integration Hub](/products/integration-hub). It reads Coupa's Core API on a schedule and writes Coverbase's view of each supplier and contract back to custom fields you name.
```mermaid theme={null}
flowchart LR
subgraph coupa["Coupa"]
req["Requisitions"]
sup["Suppliers"]
con["Contracts"]
bud["Budget lines"]
end
subgraph cb["Coverbase"]
intake["Draft intake request"]
vendor["Vendor link and approved supplier status"]
contract["Contract record"]
spend["Spend Controls"]
end
req --> intake
sup --> vendor
con --> contract
bud --> spend
vendor -->|risk tier, approval status| sup
contract -->|risk rating| con
```
## What it does
| Coupa object | Direction | What happens in Coverbase |
| - | - | - |
| Requisitions | In | A draft intake request with the requisition's total, commodity and requester, shown to the Front Door as **Started From Procurement**. You choose which requisition statuses open one. |
| Suppliers | In | Linked to one of your organization's vendors on tax ID or D-U-N-S, or on website when nothing stronger disagrees. The supplier's `approved-supplier` custom field, or its status, sets the vendor's approved supplier status for Coupa. |
| Suppliers | Out | Risk tier and approval status, written to the supplier custom fields you name. |
| Contracts | In | Start date, end date and maximum value. A contract Coupa reports as published is marked executed in Coverbase. |
| Contracts | Out | Risk rating (the vendor's residual risk, else its tier), and optionally the required clause pack and blocking issues, written to the contract custom fields you name. |
| Budget lines | In | Budget amount and committed spend, shown on **Spend Controls** and used by the intake budget step. |
Syncs read only records updated since the last successful sync. Outbound values are written only when they changed since the last push.
## Authentication
Coupa uses OAuth 2.0 client credentials (Coupa's OIDC client) at `/oauth2/token`.
1. In Coupa, create an OAuth client with the client credentials grant and these scopes: `core.supplier.read`, `core.supplier.write`, `core.requisition.read`, `core.contract.read`, `core.contract.write` and `core.budget.read`. Coverbase asks for all six when it requests a token, so grant all six even if you leave write-back off.
2. Create the custom fields Coverbase will write to on suppliers and contracts, for example `coverbase_risk_tier`, `coverbase_approval_status` and `coverbase_risk_rating`.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **Coupa**.
2. On **Authentication**, enter the **Instance URL**, **Client ID** and **Client secret**.
3. Turn on **Open an intake request for each new requisition** if you want one, and pick the **Requisition Statuses**.
4. Turn on **Write risk tier, approval status and contract values back to the provider** for two-way sync.
5. Set **Sync Interval (Minutes)** and click **Save**, then **Test connection**.
6. On **Field Mappings**, put your Coupa custom field API names in each outbound row's **Target**, and **Save mappings**.
7. Click **Sync now** and read the **Sync Log**.
## Webhooks
Coupa does not sign outbound calls the way Coverbase requires. To have a record change trigger a sync, put middleware (an integration platform or a small function) between Coupa and Coverbase that signs each call with the connection's signing secret. See [Set up the webhook](/user-guides/integration-hub#step-3-set-up-the-webhook-optional). Without one, the scheduled sync picks up every change.
## Onboarding checklist
1. An OAuth client with the scopes above.
2. Custom fields on suppliers and contracts for the values Coverbase writes back.
3. Agreement on which requisition statuses should open an intake request.
4. A steward to work the steward queue for suppliers that do not match.
## Related
Field mappings, the sync log and the steward queue.
Where a synced requisition is reviewed.
The other procure-to-pay connector.
How the client secret and signing secret are kept.
# DocuSign
Source: https://docs.coverbase.com/integrations/guides/docusign
Send vendor documents for e-signature without leaving Coverbase, through your own DocuSign account.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase connects to **DocuSign** so documents that come out of the vendor lifecycle (agreements, attestations, approval sign-offs) go out for signature without leaving the platform, through your organization's own DocuSign account.
There are two places you can send from, and they behave the same once the envelope is out:
* **From a contract.** The **DocuSign Execution** card on the contract's **Workflow** tab, once the contract has cleared its approval chain. This is the path described in [Contract intake and approval](/user-guides/contract-intake-and-approval).
* **From a vendor document.** The document's actions menu, for anything that is not a contract record.
```mermaid theme={null}
flowchart LR
subgraph cb["Coverbase"]
doc["Vendor document"]
end
subgraph ds["DocuSign (your account)"]
envelope["Signature request"]
end
doc -->|send for signature| envelope
envelope -->|executed document| doc
```
## What it does
* **Initiate execution from the document itself.** A vendor document in Coverbase is sent for e-signature directly from its actions menu, with the envelope created in your DocuSign account. No download, no re-upload, no separate system to open.
* **Route countersignature.** Up to five signer slots are supported, each mapped to a numbered anchor in the document. Each signer carries an **order** value: signers sharing an order sign in parallel, and increasing order values route sequentially, which is how a counterparty-then-countersignature flow is expressed. Assign the vendor signer order `1` and your own authorized signatory order `2`, and the envelope reaches your side only once the counterparty has signed.
* **Track the request on the third-party record.** The signature request is stored against the Coverbase document it was raised from, carrying the DocuSign envelope ID, the recipients, and the request status as it moves through **sent**, **signed**, **completed** and **declined**. The status of an in-flight execution is a field on the record rather than something to go and look up.
* **The executed agreement stays bound to the record.** Because the envelope is created **from** a Coverbase vendor document, the fully executed agreement is attached to that third party's record by construction, not by someone remembering to file it. From there it flows into the contract family: [Contract Guardian](/products/contract-guardian) runs the clause review, [Document Insights](/products/document-insights) extracts dates, values, notice periods and liability caps, and obligations are tracked against it.
* **Your account, your audit trail.** Envelopes live in your DocuSign tenant, so your existing DocuSign retention, compliance, and audit posture applies unchanged, including the DocuSign certificate of completion.
* **Multi-account aware.** Users who belong to several DocuSign accounts pick which one to send from; Coverbase respects DocuSign's account membership rather than assuming one.
* **Send on approval, without anybody pressing send.** A contract approval policy can carry **Send for signature on approval**. The requester names who signs while the contract is still in its chain, and the envelope goes out as them as soon as the last approver signs off. See [Sending automatically](/user-guides/contract-intake-and-approval#sending-automatically).
## Preparing a document for signature
Coverbase maps signer slots using numbered anchor tags placed in the document text, so fields land where your paper puts them rather than where a template guesses.
| Field | Anchor tags |
| - | - |
| Signature, required per signer slot | `/sn1/` through `/sn5/` |
| Signed date, filled automatically | `/date_signed1/` through `/date_signed5/` |
| Date, recipient-editable | `/date1/` through `/date5/` |
| Title, recipient-editable | `/title1/` through `/title5/` |
| Organization, recipient-editable | `/organization1/` through `/organization5/` |
Each signer needs a unique signature anchor and a unique email address. Coverbase validates both before sending, and refuses a document whose anchors are missing rather than producing an envelope with nowhere to sign.
Put the anchor set into your standard MSA, DPA and order-form templates once. Every agreement generated from them is then sendable with no preparation step at all.
## Connecting your account
Connecting is per person, not per organization. Each sender authorizes Coverbase against their own DocuSign login, so envelopes carry the right sender and your DocuSign permissions apply unchanged.
Go to a contract's **Workflow** tab and click **Send to DocuSign** on the DocuSign Execution card, or open a vendor document's actions menu and choose **Send for Signature**. If you are not connected yet, Coverbase says so and offers **Connect DocuSign**.
Clicking **Connect DocuSign** opens DocuSign in a new tab. Sign in with your normal DocuSign credentials and grant Coverbase access. Coverbase never sees your DocuSign password.
DocuSign returns you to the screen you started from. The send dialog now shows your connected account instead of the connect prompt, and stays connected on your other devices too.
People who belong to more than one DocuSign account get an account selector. Coverbase preselects the account your organization configured, falls back to your DocuSign default, and lets you change it per send.
**If you belong to several DocuSign accounts and your organization has configured one you are not a member of**, Coverbase warns you and uses your own default instead of failing the send. Ask your DocuSign administrator to add you to the configured account if envelopes should be raised there.
### Setting the organization account
An administrator sets which DocuSign account the organization sends from under **Configuration → External Integrations → DocuSign**. This is a default, not a restriction: senders may still pick another account they belong to.
### Disconnecting
The send dialog's account card has a **Disconnect** action. It forgets your grant, so nothing can send as you until you authorize again. Envelopes already in flight are unaffected, and reconnecting takes one authorization round trip.
**Connect once, not once per device.** Your grant is held against your Coverbase user, so connecting on a laptop is also connected on a phone. Clearing site data does not disconnect you; **Disconnect** does.
**You can only ever send as yourself.** Coverbase resolves the DocuSign identity from your own grant, never from anything the screen sends, so no colleague's account is reachable from your session even if you can edit the contract. A person who has not connected sees the connect prompt rather than somebody else's account.
An automatic send on approval is the one case where an envelope goes out with no browser open, and it is still your own grant: the envelope is sent as the person who **set up that send**, never as the submitter and never as whichever approver clicked last. Disconnecting stops those too.
## Keeping status in step
Once an envelope is out, three things keep Coverbase's copy of its status honest:
| Mechanism | When it runs |
| - | - |
| **DocuSign Connect** | Immediately, as DocuSign moves the envelope. Coverbase verifies the signature on every callback and rejects anything unsigned. |
| **Scheduled reconciliation** | On a schedule, re-reading every envelope that is still in flight. This is the safety net for a callback that never arrived. |
| **Sync status** | On demand, from the button on the envelope, for when you are watching a signature land. |
Ask your Coverbase contact to enable DocuSign Connect for your account if envelope statuses only update when you press **Sync status**.
## Onboarding checklist
1. A DocuSign account with API access enabled (standard on business plans).
2. Each sender authorizes Coverbase from a send screen, as above.
3. An administrator sets the organization's DocuSign account under **Configuration → External Integrations**, if you want a shared default.
4. Anchor tags added to the document templates you intend to send.
5. DocuSign Connect enabled, so statuses update without anyone pressing a button.
6. If you want approvals to send on their own, an approval policy with **Send for signature on approval** under **Configuration → Organization → Contract Approvals**.
## Related
Clause review before execution, and re-evaluation on amendment.
Raising a request, confirming its values, and the approval chain before a send.
Where the executed agreement lands, and what the record then tracks.
Notice windows and renewal deadlines derived from the executed paper.
The other CLM and e-signature platforms Coverbase connects with.
# EcoVadis
Source: https://docs.coverbase.com/integrations/guides/ecovadis
Sync EcoVadis sustainability scorecards into the Certificate Vault daily, for prequalification rules to read.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The EcoVadis connector feeds the [Certificate Vault](/products/certificate-vault). You bring your own EcoVadis subscription, and Coverbase reads it with your credentials once a day.
If a EcoVadis response does not have the shape Coverbase expects, the sync stops and records the error. It never treats such a response as an empty list, because an empty pull archives every certificate the network supplied.
## What it does
EcoVadis publishes a sustainability scorecard for each rated company. Coverbase reads the scorecards shared with your account and writes each as an **EcoVadis rating**, with its ESG score, into the vault.
* **Matched to your vendors.** Each record is matched to a vendor by a match recorded on an earlier run, then by its domain (walking up to the parent domain, never down), then by its exact legal name. A record that matches no vendor is skipped.
* **Kept current.** A network record is keyed by the network's ID and the certificate type. A complete pull archives records the network no longer returns.
* **Read by prequalification.** Network grade, network status and safety or ESG figure conditions in your [prequalification rule sets](/user-guides/certificate-vault#step-4-write-a-prequalification-rule-set) read these records. Only current records count.
## Authentication
EcoVadis issues a token from `https://api.ecovadis-survey.com/EVToken` for an API user name and password. Coverbase reads scorecards from `/v2/scorecards`.
1. Ask EcoVadis for API access for your account.
2. Note the API user name and password.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **EcoVadis**.
2. Enter **Username** and **Password**.
3. Click **Save**, then **Test connection**.
4. On the **Certificates** page, the **Networks** card shows EcoVadis as connected, with its certificate count and last sync. Click **Sync now** for the first pull.
If a sync fails, the panel and the **Networks** card show **The last sync failed** with the reason. Only Coverbase's own error messages are stored, never a credential or the provider's response. **Remove** deletes the stored credentials; certificates already pulled stay.
## Related
The vault, rule sets and overrides.
What prequalification does.
Prequalification on an intake request.
Every system Coverbase connects to.
# ERM risk register (REST)
Source: https://docs.coverbase.com/integrations/guides/erm-register
Push each Coverbase vendor's risk into an enterprise risk register that has a REST API but no dedicated connector, through the Integration Hub.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The ERM risk register connector is part of the [Integration Hub](/products/integration-hub). It is for an enterprise risk register with a REST API and no dedicated Coverbase connector. You describe the register's create and update endpoints, and Coverbase pushes a risk per rated vendor. It writes only; it reads nothing back.
## What it pushes
* **Vendor risk**: every vendor with a residual or inherent risk level, plus every vendor already pushed.
Each risk is created the first time and updated after that, and only when one of its mapped values changed. Coverbase keeps a link from each vendor to its register record, which the sync log shows.
| Coverbase value | Default key | What it holds |
| - | - | - |
| **Title** | `title` | The vendor's name followed by "third party risk" |
| **Vendor** | `third_party` | The vendor's name |
| **Residual risk** | `residual_risk` | The vendor's residual risk level |
| **Inherent risk** | `inherent_risk` | The vendor's inherent risk level |
| **Risk tier** | `tier` | The vendor's tier |
| **Approval status** | `approval_status` | The vendor's status |
| **Open findings** | `open_issue_count` | How many open findings the vendor has |
| **Coverbase reference** | `external_reference` | The vendor's Coverbase ID |
| **Coverbase link** | `source_url` | A link to the vendor |
Every value is written as text. A value with a blank target is not written.
## Status read back
This connector does not read anything back.
## Authentication
The register takes an API token in a header you name.
1. Create an API token for Coverbase in the register.
2. Note the path that creates a risk (for example `/risks`), the path that updates one with `{id}` in it (for example `/risks/{id}`), whether updates use `PUT` or `PATCH`, and the key in the create response that holds the new risk's ID (a dot path reaches into nested objects).
3. Note the JSON key for each value Coverbase should send.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **ERM Risk Register**, or open it from the **GRC and ERM** category of the Integration Hub.
2. On **Authentication**, enter the **Instance URL** and **API Token**. Under **Risk Register Endpoint**, set the **Token Header** (**Authorization** sends the token as a bearer token), the **Create Path**, the **Update Path**, the **Update Method** and the **ID Field**. Paths start from the instance URL's host.
3. Turn on **Push findings and vendor risk to ERM Risk Register**, set the **Sync Interval (Minutes)**, click **Save**, then **Test connection**.
4. On **Field Mappings**, check the JSON key for each value under **Vendor Risk** (dot paths nest), and **Save mappings**.
5. Click **Sync now** and read the **Sync Log**.
## When a response is not what Coverbase expects
A create response without an ID at the key you named fails that record, with the reason in the sync log.
If a create succeeds in the provider but Coverbase fails to save its link to the new record, the next sync creates a second record instead of updating the first. Remove any duplicate it leaves in the provider.
## Related
Field mappings and the sync log.
Building your own sync on the API instead.
The findings pushed as issues.
How the credentials are stored.
# Icertis
Source: https://docs.coverbase.com/integrations/guides/icertis
Two-way sync with Icertis Contract Intelligence through the Integration Hub: agreements and their executed copies sync in and mark the Coverbase contract executed, and Coverbase writes its risk rating, required clause pack and blocking issues to agreement attributes you name.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Icertis connector is part of the [Integration Hub](/products/integration-hub). It reads agreements from the Icertis Contract Intelligence (ICI) REST API and writes Coverbase's risk view back as agreement attributes.
## What it does
| Direction | What syncs |
| - | - |
| In | Each agreement's status, effective date, expiry date and contract value. Draft, in review, approved, waiting for signature, executed, expired and terminated statuses are read. An executed agreement marks its Coverbase contract executed through the same path DocuSign uses, and its executed copy is filed against the vendor once the supplier is linked. |
| Out | The vendor's risk rating, the required clause pack and the vendor's blocking issues, written to the agreement attributes you name. |
The required clause pack is the high and critical clauses of your active clause sets, up to 25, by clause ID and name. Blocking issues are the titles of the vendor's open findings, up to 20.
## Authentication
ICI tenants sit behind your identity provider, so the token URL is part of the connection. The grant is OAuth 2.0 client credentials.
1. In your identity provider, register a client for Coverbase with the client credentials grant and access to the ICI API. Note the token URL, client ID, client secret and any scope it needs.
2. In Icertis, create agreement attributes for the values Coverbase writes back, for example `CoverbaseRiskRating`, `CoverbaseClausePack` and `CoverbaseBlockingIssues`.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **Icertis**.
2. On **Authentication**, enter the **Instance URL**, **Token URL**, **Client ID**, **Client secret** and, if needed, **Scope**.
3. Turn on write-back, set the **Sync Interval (Minutes)**, click **Save**, then **Test connection**.
4. On **Field Mappings**, check the outbound **Target** attribute names and **Save mappings**.
5. Click **Sync now** and read the **Sync Log**.
## Onboarding checklist
1. A client in your identity provider, and the token URL.
2. Agreement attributes for the values Coverbase writes back.
## Related
Field mappings and the sync log.
The other contract lifecycle connector.
What happens when a contract is executed.
How the client secret is kept.
# Integration platforms (Workato, MuleSoft, Boomi)
Source: https://docs.coverbase.com/integrations/guides/integration-platforms
Connect Coverbase to Workato, MuleSoft or Boomi with Coverbase's starting points (a Workato custom connector, a Mule 4 application template and a Boomi process recipe) built on OAuth 2.0 client credentials, the REST API and signed webhooks, including pushing risk data into an enterprise risk register.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase has a starting point for each of the three common integration platforms: a Workato custom connector, a Mule 4 application template and a Boomi process recipe. Each sits on the same public surfaces, [OAuth 2.0 client credentials](/integrations/guides/oauth-client-credentials), the REST API and [signed webhooks](/integrations/webhooks), so a recipe behaves the same on any of them, and any other platform can follow the same pattern with its own HTTP connector. Ask your Coverbase representative for the starting point you need.
These are templates you import into your own Workato, Anypoint or Boomi tenant. They are not marketplace connectors.
## The building blocks
| Need | Coverbase piece |
| - | - |
| Authenticate | An OAuth client and the token URL `https://api.coverbase.app/v1/oauth/token`, or an `ak_*` key as a bearer header |
| React to changes | [Webhooks](/integrations/webhooks): Coverbase posts each event to your platform's webhook trigger, signed with `Coverbase-Signature` |
| Read records | The [API reference](/api-reference/vendors), including [contract records](/api-reference/contract-records) and [engagement records](/api-reference/engagement-records), and the [Export API](/export-api-concepts) |
| Write records | The vendor, assessment, finding and other write endpoints, and the [Import API](/import-api) |
| Bulk analytics | [Warehouse data share](/products/warehouse-data-share), when the destination is a warehouse rather than an application |
## Rules every recipe follows
* **A webhook is a nudge.** It carries the event type and the record ID. Read the record again through the API before writing it anywhere, so a late or retried delivery never overwrites newer data with older data.
* **Verify before anything else.** Reject a delivery whose `Coverbase-Signature` does not match (hex HMAC-SHA256 of the raw body, keyed by your webhook secret) or whose `Coverbase-Timestamp` is more than five minutes old.
* **Deduplicate on `event_id`.** A retried delivery keeps its `event_id`, so acknowledge one you already handled and do nothing.
* **Reconcile on a schedule.** Webhooks are not a guarantee while your target is down. Page the list routes nightly (`limit=200`, then `offset`) and upsert.
* **Open an intake, not a vendor.** To bring in a new supplier, use the [Intake API](/api-reference/intake) so the Front Door triages it. A bare vendor record carries no due diligence.
## Workato
The custom connector is built with the Workato connector SDK. Paste it into a new custom connector in the SDK console, or push it with the Workato gem.
1. Create an OAuth client in Coverbase and grant only the scopes your recipes need.
2. In Workato, create a connection with the client ID and secret. The connector requests tokens from `POST /v1/oauth/token` with HTTP Basic credentials and fetches a new one whenever a request returns `401`.
3. Use its actions: search, get and create vendors; list and get engagement records; list, get, create and update contract records; list, get, create and update findings; and a custom request for any other public route.
4. Use its triggers for new or updated vendors, engagement records, contract records and findings. Turning a recipe on registers a Coverbase webhook for it and turning it off deletes it. Each delivery is verified before the recipe sees it. Restart recipes after rotating the OAuth client secret, so they re-subscribe.
## MuleSoft
The Mule 4 application template imports into Anypoint Studio.
* An HTTP request configuration with OAuth 2.0 client credentials against the token URL, refreshed on `401`.
* A webhook listener at `/coverbase/events` that verifies the signature and timestamp, and acknowledges a repeated `event_id` without acting.
* A routing flow that reads the current finding, contract record, engagement record or vendor from the API and hands it to a target flow, and a nightly reconcile flow over findings.
* Replace the target sub-flows with the operations for your system, keyed on the Coverbase ID (or the finding number), and keep the client secret and webhook secret in secure properties.
## Boomi
The Boomi recipe gives you what you cannot click together on the canvas: a Groovy script that verifies the signature and timestamp, and JSON profiles for the webhook envelope, findings, engagement records and contract records.
1. Create an HTTP Client connection to `https://api.coverbase.app` with OAuth 2.0 client credentials and the token URL.
2. Start the process with a Web Services Server listener that keeps the raw body, run the signature script first, drop a repeated `event_id`, route on `event_type`, read the current record with a GET operation, map it, and upsert it.
3. Register the listener URL once as a Coverbase webhook, with the same secret the script uses.
## Pushing to an enterprise risk register
Archer, ServiceNow IRM and REST risk registers have built-in connectors in the Integration Hub: see [Archer](/integrations/guides/archer), [ServiceNow IRM](/integrations/guides/servicenow-irm) and [ERM risk register](/integrations/guides/erm-register). For a register those do not fit, two patterns work through an integration platform, and the starting points above include both:
* **Event-driven.** Subscribe to finding and assessment events with a webhook. In your platform, fetch the full record from the API and create or update the matching risk or issue in the register.
* **Batch.** Read engagements, contracts, findings and exceptions on a schedule from the API, or from the tables in [warehouse data share](/products/warehouse-data-share), and load them into the register.
Store the register's record ID back on the Coverbase record (for example as a custom field) so later updates find it. For ServiceNow, the [ServiceNow integration](/integrations/guides/servicenow) creates and updates records natively from workflows.
## Related
Create a client and test a token.
Events, payloads and signature verification.
Inbound, outbound and bidirectional patterns.
Every system Coverbase connects to.
# Ironclad
Source: https://docs.coverbase.com/integrations/guides/ironclad
Two-way sync with Ironclad through the Integration Hub: records and their signed copies sync in and mark the Coverbase contract executed, and Coverbase writes its risk rating, required clause pack and blocking issues to record properties you name.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Ironclad connector is part of the [Integration Hub](/products/integration-hub). It reads Ironclad's Records API, the repository of agreements, and writes Coverbase's risk view back onto each record.
## What it does
| Direction | What syncs |
| - | - |
| In | Each record's agreement date, expiration date and contract value. A record with a `signedCopy` attachment is executed: Coverbase marks its contract executed through the same path DocuSign uses, so the executed notice and accounting packet fire, and files the signed copy against the vendor once the supplier is linked. A record whose status is expired or terminated is recorded as such. |
| Out | The vendor's risk rating, the required clause pack and the vendor's blocking issues, written as string properties on the record under the property keys you name. |
The required clause pack is the high and critical clauses of your active clause sets, up to 25, by clause ID and name, separated by semicolons. Blocking issues are the titles of the vendor's open findings, up to 20.
## Authentication
Ironclad uses a bearer API token.
1. In Ironclad, create an API token with access to records, and note your instance URL.
2. Create record properties for the values Coverbase writes back, for example `coverbaseRiskRating`, `coverbaseClausePack` and `coverbaseBlockingIssues`.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **Ironclad**.
2. On **Authentication**, enter the **Instance URL** and **API token**.
3. Turn on **Write risk tier, approval status and contract values back to the provider** for two-way sync, set the **Sync Interval (Minutes)**, click **Save**, then **Test connection**.
4. On **Field Mappings**, check each outbound row's **Target** matches your property keys, and **Save mappings**.
5. Optionally create a webhook signing secret so Ironclad, through middleware that signs the call, can trigger a sync when a record changes. See [Set up the webhook](/user-guides/integration-hub#step-3-set-up-the-webhook-optional).
6. Click **Sync now** and read the **Sync Log**.
## Onboarding checklist
1. An API token and the instance URL.
2. Record properties for the values Coverbase writes back.
3. Vendors in Coverbase for the counterparties you contract with, so executed copies file against them.
## Related
Field mappings and the sync log.
The other contract lifecycle connector.
What happens when a contract is executed.
The clause sets the required clause pack comes from.
# ISNetworld
Source: https://docs.coverbase.com/integrations/guides/isnetworld
Sync ISNetworld contractor grades, safety statistics and insurance into the Certificate Vault daily, for prequalification rules to read.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The ISNetworld connector feeds the [Certificate Vault](/products/certificate-vault). You bring your own ISNetworld subscription, and Coverbase reads it with your credentials once a day.
If a ISNetworld response does not have the shape Coverbase expects, the sync stops and records the error. It never treats such a response as an empty list, because an empty pull archives every certificate the network supplied.
## What it does
ISNetworld grades contractors on safety, insurance and compliance for the hiring clients that sponsor them. Coverbase reads the grades for your hiring client account and writes each contractor's **ISNetworld grade**, with its expiry date, safety statistics (such as TRIR, EMR and DART rate) and insurance into the vault.
* **Matched to your vendors.** Each record is matched to a vendor by a match recorded on an earlier run, then by its domain (walking up to the parent domain, never down), then by its exact legal name. A record that matches no vendor is skipped.
* **Kept current.** A network record is keyed by the network's ID and the certificate type. A complete pull archives records the network no longer returns.
* **Read by prequalification.** Network grade, network status and safety or ESG figure conditions in your [prequalification rule sets](/user-guides/certificate-vault#step-4-write-a-prequalification-rule-set) read these records. Only current records count.
## Authentication
ISNetworld uses OAuth 2.0 client credentials at `https://api.isnetworld.com/oauth/token`. With an account ID, Coverbase reads `/v1/hiring-clients//contractors`; without one, `/v1/contractors`.
1. Ask ISNetworld for API client credentials for your hiring client account.
2. Note your hiring client ID.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **ISNetworld**.
2. Enter **Client ID**, **Client Secret**, and **Account ID** (your hiring client ID).
3. Click **Save**, then **Test connection**.
4. On the **Certificates** page, the **Networks** card shows ISNetworld as connected, with its certificate count and last sync. Click **Sync now** for the first pull.
If a sync fails, the panel and the **Networks** card show **The last sync failed** with the reason. Only Coverbase's own error messages are stored, never a credential or the provider's response. **Remove** deletes the stored credentials; certificates already pulled stay.
## Related
The vault, rule sets and overrides.
What prequalification does.
Prequalification on an intake request.
Every system Coverbase connects to.
# Jira
Source: https://docs.coverbase.com/integrations/guides/jira
Create Jira issues from Coverbase workflows: findings, follow-ups, and remediation work land in the backlog your engineering teams already run.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase creates issues in your Jira directly. Remediation work discovered during vendor risk reviews (a finding to chase, an internal control to fix, a follow-up to schedule) lands in the backlog your teams already triage, instead of living only inside the risk platform.
```mermaid theme={null}
flowchart LR
subgraph cb["Coverbase"]
wf["Workflow engine"]
obj["Findings · follow-ups · assessments"]
end
subgraph jira["Jira"]
issue["Issue in your project"]
end
obj --> wf
wf -->|create issue| issue
```
## What it does
* **Create jira ticket is a native workflow action.** Any [workflow](/integrations/workflow-engine) can create a Jira issue at the right moment (when a finding is confirmed, when an assessment completes with open issues, when a follow-up goes unanswered). You set the project key, the summary and the description, which can insert variables from the triggering object, and optionally an assignee. Issues are created with the **Task** issue type.
* **A test ticket from the configuration dialog.** **Create test ticket** on the Jira card raises a simple issue in a project you name, so you can confirm the connection before a workflow depends on it.
* **One-way.** Coverbase creates the issue and records it on the workflow run. It does not read the issue's status back or move it through your Jira workflow.
## Authentication and provisioning
The connector authenticates to Jira Cloud with an account email and API token (standard Atlassian token auth), stored per-organization in Coverbase's secrets manager and configured self-serve on the **Configuration → External Integrations** page: open the **JIRA** card and enter the **JIRA URL**, **Account identifier** and **API token**, then **Save JIRA Configuration**. Scope it to a service account with access to the target projects.
## Onboarding checklist
1. A Jira service account with create/edit permission in the target projects, and its API token.
2. The project keys Coverbase should create into. Each project needs the **Task** issue type.
3. The workflow moments that should raise tickets, configured in the [workflow engine](/integrations/workflow-engine) and changeable by your team at any time.
Prefer events over tickets? Jira can also consume Coverbase [webhooks](/integrations/webhooks) through Atlassian automation if you want full control of issue creation on your side.
# Microsoft Teams
Source: https://docs.coverbase.com/integrations/guides/microsoft-teams
Post the Coverbase notifications you choose to a Microsoft Teams channel as Adaptive Cards, approve or decline Front Door sign-offs, acceptance decisions and exit evidence from the card through your Coverbase bot, and take intake requests in Teams chats.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Microsoft Teams connector is part of the [Integration Hub](/products/integration-hub). It posts the notification types you choose to one Teams channel, so a team sees new reviews, decisions and alerts where it already talks.
```mermaid theme={null}
flowchart LR
n["Coverbase notification"] --> d{"Type selected?"}
d -->|yes| c["Adaptive Card"]
c -->|Workflows or incoming webhook| ch["Teams channel"]
```
## What it does
* **One post per event.** A Coverbase notification can go to several people. The channel gets it once, however many recipients it had.
* **An Adaptive Card.** Each post carries the notification's title, its text (shortened past 2,000 characters) and, when the notification links somewhere, a button that opens the record in Coverbase.
* **Never in the way.** If Teams is unreachable or rejects a post, the notification still reaches its recipients in Coverbase and by email.
With a Coverbase bot registered in your Azure tenant, three kinds of card also carry **Approve** and **Decline** buttons: a Front Door disposition waiting on a sign-off group, a finding's acceptance chain waiting on a recommendation, decision or approval, and exit plan evidence waiting on its approver. The same bot lets people request a vendor by chatting with it (see the [Intake Agent](/user-guides/intake-agent)).
## Authentication
The connector posts to a webhook URL that you create in Teams. The URL is itself the credential: anyone who holds it can post to the channel. Coverbase stores it in a secrets manager and only ever shows its host.
1. In the Teams channel, create a **Workflows** webhook (the "Post to a channel when a webhook request is received" template), or a legacy incoming webhook connector.
2. Copy the URL. Coverbase accepts HTTPS URLs on `webhook.office.com`, `logic.azure.com` and `environment.api.powerplatform.com` hosts only.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **Microsoft Teams**.
2. On **Authentication**, paste the **Webhook URL**.
3. Under **Notification Types**, choose which notifications post. Each one posts once to the channel, whoever it was for.
4. Click **Save**, then **Send test message** and check the channel.
To post to a different channel, replace the webhook URL. To stop posting, **Pause** or **Disconnect** the connection.
## Register the bot
Approvals and Teams intake need a bot registered in your own Azure tenant. The incoming webhook above keeps working without it.
1. In the Azure portal, create an **Azure Bot** resource. For the type of app choose **Single Tenant**, and let Azure create a new Microsoft App ID.
2. Open the bot's **Configuration** and copy the **Microsoft App ID** and the **App Tenant ID**. Under **Manage Password**, create a client secret and copy its value.
3. In Coverbase, open the Microsoft Teams connection's **Authentication** tab. Enter the **Bot app ID**, **Bot client secret** and **Directory (tenant) ID**, turn on **Approve and decline from Teams cards**, and save. Copy the **Messaging Endpoint** it shows.
4. Back in Azure, paste it into the bot's **Messaging endpoint** and save.
5. Under **Channels**, add **Microsoft Teams** and accept the terms.
6. Build a Teams app package for the bot in the Developer Portal for Teams: a new app with a **Bot** feature using the app ID, in the **Team** and **Personal** scopes. Have a Teams admin upload it to your organization's app catalog.
7. Add the app to the team, then to the channel that should receive approval cards. The connection's **Approval Cards** status reads **Posting to** that team and channel once Teams tells the bot it was added.
8. In the Microsoft Teams connection's **Notification Types**, choose the approval notifications to post.
The **Approval Cards** status is **Live**, **Needs the bot** (approvals on but no app ID and secret, so cards post without buttons), **Needs a channel**, or **Off**.
## Deciding from a card
* **You act as yourself.** The first time someone presses a button, Coverbase looks them up in Microsoft's roster for the conversation and matches the address to an active member of your organization. They then decide with their own Coverbase permissions, so a person who cannot decide in the dashboard cannot decide in Teams. Nothing on the card identifies anyone.
* **A press counts once.** If Teams delivers a press twice, it is recorded once. A press on a card someone already decided reports it as decided.
* **A card is tied to what it showed.** If the disposition was revised or the acceptance chain moved on after the card was posted, the press is refused rather than applied to a decision the presser never saw.
* **Decline needs a reason.** Declining a Front Door sign-off does what **Decline** does in Coverbase: the disposition goes back to the TPRM Office as a draft, both sign-offs clear, the reason goes on the audit trail, and the person who recorded the disposition, the TPRM Office group and the requester are notified. Declining an acceptance step records remediation or rejection. Returning exit evidence reopens the step for its owner.
* **One card per event, kept current.** A Front Door card posts once for both sign-off groups. When someone presses a button, the card is replaced with the outcome. When someone signs off or declines in Coverbase instead, the card is replaced too. It then shows who signed and which group is still waiting, the decided disposition once both groups have signed, or who declined and why.
* **An outage never loses a notification.** If approvals are off, the bot is not in a channel, or a post fails, the plain card goes out instead.
The **Approvals** tab lists every **Approve** and **Decline** pressed: the time, the person, the request, the outcome (**Recorded**, **Already decided**, **Not allowed**, **Account not matched**, **Not recorded** or **Failed**) and the detail.
Coverbase checks that every message to the bot is signed by Microsoft for your bot, with your app ID, and from your tenant when you gave one. It sends the bot's token only to Microsoft's Bot Connector hosts.
## Related
The notifications you can choose from.
The Slack app.
Connecting and pausing a connection.
Sending structured events to your own systems instead.
# Moody's
Source: https://docs.coverbase.com/integrations/guides/moodys
Bring Moody's long-term credit ratings for your portfolio into Coverbase: each vendor's rating is recorded, and a downgrade becomes a Radar signal.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Moody's connector is a licensed rating connector: you bring your own Moody's subscription, and Coverbase reads your portfolio with your credentials. It works like the [Black Kite integration](/user-guides/black-kite-monitoring). Ratings land on the vendor's **Certificates** tab under **Licensed Ratings**, and changes become [Radar](/products/supplier-radar) signals.
If a Moody's response does not have the shape Coverbase expects, the pull stops and the panel shows **The last sync failed** with the reason, instead of reading the response as an empty portfolio.
## What it does
* **Provisions monitoring once.** The first time you save credentials, Coverbase adds one Moody's source to Radar and one detector on it, named for a credit rating drop. Both are created once. Archiving the source stops monitoring, and saving new credentials later does not bring it back.
* **Matches companies to vendors.** Each company in your portfolio is matched to a vendor by a match recorded on an earlier pull, then by its domain (walking up to the parent domain, never down), then by its exact legal name. A company that matches no vendor is skipped.
* **Records the rating.** Each pull records the matched vendor's long-term credit rating, from Aaa (best) to C, one notch per step.
* **Signals only on change.** A Radar item is raised only when a stored rating moved. The first pull is a baseline, so connecting a provider does not flood Radar.
## The detector
The detector starts enabled, alerting on a drop of 2 notches or more between pulls. Edit it like any other Radar detector. It has three gates, and at least one must be set. A rating change alerts only when it passes every gate that is set. **Minimum drop** and **Alert below** take zero or more, in the provider's own units.
| Gate | Passes when |
| - | - |
| Minimum drop | The rating fell by at least this much since the last pull. |
| Alert below | The rating is below this value. |
| Grade worsened | The provider's grade or band got worse. |
Alerts go through the ordinary Radar path, so reassessment triggers and monitoring plan signal rules see them like any other signal.
## Authentication
Moody's uses OAuth 2.0 client credentials at `https://api.moodys.com/oauth2/token`. Coverbase reads your portfolio entities from `/entity-risk/v1/portfolio/entities`.
1. Ask Moody's for API client credentials with access to your entity portfolio.
2. Add the vendors you want monitored to that portfolio.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **Moody's Analytics**.
2. Enter **Client ID**, **Client Secret**. The panel notes: "Saving the credentials adds a Moody's source to Radar for credit rating changes."
3. Click **Save**, then **Test connection**.
4. Open **Radar** to find the new source and its detector.
The panel never shows a stored secret again. **Remove** deletes the stored credentials; ratings already pulled stay.
## Related
Where licensed ratings show on a vendor.
Triaging the signals a rating change raises.
Letting a rating drop pull monitoring forward.
Coverbase's own outside-in rating, which needs no subscription.
# OAuth 2.0 client credentials
Source: https://docs.coverbase.com/integrations/guides/oauth-client-credentials
Authenticate an integration to the Coverbase public API with an OAuth 2.0 client instead of a long-lived API key: create the client, store the secret, request short-lived tokens, and revoke.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Many integration platforms and GRC tools expect OAuth 2.0 rather than a static API key. An OAuth client gives them that: the platform holds a client ID and secret, asks Coverbase for a bearer token when it needs one, and uses the token until it expires, at most an hour later. The token reaches exactly what an `ak_*` key reaches. Endpoint details are in the [OAuth API](/api-reference/oauth) reference.
## When to use it
| Use | When |
| - | - |
| An `ak_*` [API key](/api-reference/api-keys) | Your integration can keep one long-lived secret and send it on every call. |
| An OAuth client | Your platform has an OAuth 2.0 client credentials connection type, your security policy prefers short-lived tokens, or you want to narrow a token's scopes per job. |
Both authenticate as your organization's API service account. The [IP allowlist](/conventions#api-ip-allowlist), the [public API audit log](/conventions#public-api-audit-log) and every route's permissions apply the same way.
## Step 1: Create the client
1. Open **Configuration** and choose **API keys**.
2. Under **OAuth Clients**, click **New client**.
3. Give it a **Name**, such as "GRC sync".
4. Under **Elevated Scopes**, choose any scopes the integration needs. Most need none, which the list shows as **Standard access**. Only an admin signed in to the dashboard can grant scopes.
5. Click **Create client**.
6. Copy the **Client ID** and **Client Secret**, store the secret in your platform's secret store, and click **I saved the secret**. The secret is not shown again.
Tokens from a client made on this page last one hour. To create a client with a shorter token lifetime, from five minutes up, use `POST /v1/api-oauth-clients` with `access_token_ttl_seconds`.
## Step 2: Configure your platform
In your integration platform's OAuth 2.0 client credentials connection, enter:
| Setting | Value |
| - | - |
| Token URL | `https://api.coverbase.app/v1/oauth/token` |
| Client authentication | HTTP Basic (client ID and secret in the `Authorization` header). Sending them as form fields instead also works, but never both in one request. |
| Grant type | `client_credentials` |
| Scope | Leave empty for every scope the client holds, or list a subset, space-separated |
| Token placement | `Authorization: Bearer ` |
## Step 3: Test it
```bash cURL theme={null}
TOKEN=$(curl -s -X POST "https://api.coverbase.app/v1/oauth/token" \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d "grant_type=client_credentials" | jq -r .access_token)
curl -H "Authorization: Bearer $TOKEN" https://api.coverbase.app/v1/utils/authtest
```
`{"msg": "Auth successful"}` means the token works. Request a new token when `expires_in` runs out. This grant has no refresh token. Reuse a token until it expires: a client holds at most 50 live tokens, and requesting a 51st revokes its oldest.
## Revoke
On the **API keys** page, click **Revoke** on the client and confirm **Revoke client**. The client can no longer get tokens, and its current tokens stop working. A server that cached a token can keep accepting it for a few seconds. **Last Token** shows when each client last asked for a token, which helps find clients nobody uses.
## Troubleshooting
| What you see | Cause | Fix |
| - | - | - |
| No **OAuth Clients** section on the **API keys** page | The third-party lifecycle features are not on for your organization, or you are not an admin. | Ask your Coverbase representative, or an admin. |
| `401 invalid_client` | Wrong client ID or secret, or the client is revoked. | Check both values. Create a new client if the secret is lost. |
| `400 unsupported_grant_type` | `grant_type` is missing, or the body was sent as JSON. | Send `grant_type=client_credentials`, form-encoded. |
| `400 invalid_scope` | The token request asks for a scope the client was not granted. | Request fewer scopes, or create a client with the scope. |
| `403 insufficient_scope` on a call | The token lacks a scope the endpoint needs. | Request the scope when getting the token, if the client holds it. |
| `403 ip_not_allowed` | Your platform's egress IP is outside the allowlist. | Add it to the [IP allowlist](/conventions#api-ip-allowlist). |
## Related
The token endpoint and client management.
Authentication, scopes, errors and pagination.
Workato, MuleSoft and Boomi.
How client secrets are stored.
# OneTrust
Source: https://docs.coverbase.com/integrations/guides/onetrust
Coverbase assessments mirror into OneTrust as Vendor Risk Assessments, advanced through their native lifecycle, with one OneTrust risk created per unresolved issue.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase integrates with **OneTrust Third-Party Risk Management** in production today. Assessments run in Coverbase; each one is mirrored as a OneTrust **Vendor Risk Assessment (VRA)**: launched when the Coverbase assessment starts, advanced through OneTrust's native lifecycle as work progresses, and, on completion, populated with one OneTrust risk per unresolved issue before being closed out. OneTrust stays the system of record; its risk register, treatment workflows, and reporting operate on the results natively.
```mermaid theme={null}
flowchart LR
subgraph cb["Coverbase"]
assess["Assessment: evidence · AI analysis · scoring · review"]
issues["Unresolved issues"]
end
subgraph ot["OneTrust"]
vra["Vendor Risk Assessment"]
vendor["Vendor inventory record"]
risks["Risks on the VRA"]
end
assess -->|launch + lifecycle actions| vra
vra ---|linked as primary record| vendor
issues -->|one risk per unresolved issue| risks
risks --- vra
```
## Lifecycle mirroring
OneTrust drives assessment stage through lifecycle *actions*, not a status field, and the integration speaks that language:
| Coverbase state | OneTrust action | Resulting VRA stage |
| - | - | - |
| Assessment starts | Launch VRA from your template; link it to the vendor's inventory record as the primary record | In Progress |
| Assessment enters review | Submit the VRA | Under Review |
| Assessment completes | Create risks, then approve the VRA | Completed |
The vendor link uses OneTrust's primary-record mechanism, which persists through VRA completion, verified live against a customer sandbox, including the failure modes of the alternative linking approaches OneTrust silently accepts but later drops.
## Risk creation
On completion, each Coverbase issue that remains unresolved becomes a OneTrust risk attached to the VRA (mitigated issues stay in Coverbase; only exception-worthy risks are pushed):
| Coverbase | OneTrust risk field |
| - | - |
| Control identifier | Risk name |
| Issue title | Risk reason |
| Analyst's evidence-backed analysis | Risk description |
| Severity | Inherent risk level (expressed as OneTrust probability × impact heatmap factors) |
| Inverted, rescaled assessment score | Target risk level |
| Treatment notes and configured custom fields | OneTrust risk attributes |
| Risk owner assignments from the vendor record | OneTrust risk attributes |
The score translation is direction-aware: Coverbase scores run higher-is-better, OneTrust's heatmap runs higher-is-worse, so scores are inverted and rescaled onto your OneTrust matrix, pinned by tests across multiple scoring-scale shapes so a scale change never silently misbands a risk.
## Trigger model
```mermaid theme={null}
sequenceDiagram
participant CB as Coverbase
participant OT as OneTrust
Note over CB: Assessment starts
CB->>OT: Launch VRA from template
CB->>OT: Link vendor inventory record as primary record
Note over CB: Assessment enters review
CB->>OT: Submit VRA (Under Review)
Note over CB: Assessment completes
CB->>OT: Create or update one risk per unresolved issue
CB->>OT: Approve VRA (Completed)
```
The completion push runs as a background job rather than inside a user request: at real portfolio scale (an assessment can carry dozens of risks), per-risk creates plus retry pacing exceed any sensible request timeout, and a half-done batch is exactly the failure mode the design eliminates.
## Reliability
* **Create-or-update, keyed on OneTrust IDs.** The VRA ID and each risk's OneTrust ID are persisted on the Coverbase side the moment they're created. A re-run updates existing records in place with the latest data, so replays never duplicate.
* **Write-contention pacing.** Risks on a VRA contend on the linked vendor inventory record inside OneTrust; the connector paces successive creates and retries OneTrust's conflict responses, which are duplicate-safe by construction.
* **Field semantics verified live.** OneTrust's native risk fields full-replace on update while custom attributes merge, and several schema-advertised fields silently discard writes. The connector's write shapes were confirmed field-by-field against a live tenant, including re-sending the native field set on every update so nothing is silently cleared.
* **Partial pushes are reported, never silent.** A single risk failure is isolated so it doesn't block close-out, and the sync logs a tally of synced versus failed risks with their identifiers.
* **Sandbox-verified rollout.** The integration was stood up and verified end to end (launch → submit → risks → approve → read-back) against the customer's OneTrust sandbox before touching production.
## Authentication and provisioning
The connector authenticates with an org-scoped OneTrust bearer token carrying assessment and risk-module scope, stored in Coverbase's secrets manager.
## In production
Runs vendor reassessments in Coverbase against its OneTrust-resident vendor inventory: every Coverbase assessment appears as a OneTrust VRA linked to the right vendor record, moves through OneTrust's stages as analysts work, and lands its unresolved issues as OneTrust risks (sized to a real book of risks per assessment) with the fund's own custom risk attributes populated.
## Onboarding checklist
1. A OneTrust API token with assessment and risk-module scope (sandbox first).
2. A VRA template for Coverbase-driven assessments (Coverbase provides the required shape; your OneTrust admin creates it).
3. Your risk heatmap dimensions and any custom risk attributes to populate, with their option lists.
4. Vendor inventory identifiers on the Coverbase vendor records (loaded during onboarding through the [Import API](/import-api)).
# ProcessUnity
Source: https://docs.coverbase.com/integrations/guides/processunity
Bidirectional integration with ProcessUnity: assessments flow in, scored results, review decisions, issues, and documents flow back as native ProcessUnity records.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase runs bidirectional integrations with ProcessUnity in production today, at enterprise scale. ProcessUnity stays the system of record; Coverbase does the assessment work (AI-assisted questionnaire analysis, evidence collection, follow-ups, scoring, and review) and writes everything back as native ProcessUnity records, so your existing ProcessUnity reporting, dashboards, and downstream workflows keep working unchanged.
```mermaid theme={null}
flowchart LR
subgraph pu["ProcessUnity (system of record)"]
pua["Assessments & questionnaires"]
pue["Engagement requests"]
pur["Assessment records · issues · attachments"]
end
subgraph cb["Coverbase"]
imp["Import API"]
work["AI assessment · scoring · follow-ups · review"]
exp["ProcessUnity connector"]
end
pua -->|push assessment| imp
pue -->|push engagement request| imp
imp --> work --> exp
exp -->|scores · comments · review outcomes| pur
exp -->|issues · documents · status updates| pur
```
## What flows in
ProcessUnity pushes records into org-scoped Coverbase import endpoints as JSON. Two inbound flows are in production:
**Assessments.** ProcessUnity pushes a due-diligence or passive assessment covering one or more vendor services. Coverbase upserts the vendor and services (keyed on ProcessUnity's own IDs), creates the assessment with every covered service attached, records the inherent-risk questionnaire answers, and, for document-first assessment types, invites the vendor into the Coverbase portal to upload evidence. Multi-service assessments arrive as one record per service and are reconciled into a single assessment with strict consistency checks on the vendor and assessment identifiers.
**Engagement requests.** ProcessUnity pushes a new engagement (vendor, service, prior pre-screening answers, and attached files, which Coverbase fetches from ProcessUnity's AttachedFiles API). Coverbase creates an intake session, autofills the risk-evaluation questionnaire from the pushed answers and documents using AI, assigns it to the named analyst, and notifies them that a draft is ready for review. The analyst reviews, edits, and submits. The submission is exported back to the ProcessUnity engagement request automatically.
## What flows back
Coverbase writes results to ProcessUnity through its import-template API, as native records:
| Coverbase | ProcessUnity destination |
| - | - |
| Per-question scores, analyst comments, and follow-up history | Questionnaire response records (row-level upsert keyed on ProcessUnity's response ID) |
| Review outcomes per risk domain (status, reviewer, completion date, comments) | Assessment record fields |
| Whole-assessment scoring metrics (total, maximum, percentage, residual risk rating) | Assessment record fields |
| Findings requiring remediation | ProcessUnity issue records, with owner, impact, remediation date, and links back to the source question |
| Vendor-provided documents from follow-ups | Assessment attachments |
| Assessment status transitions (for example, entering SME review, completion) | Assessment status field |
| Submitted intake answers and their AI summary | Engagement request fields |
Every record carries a link back to the Coverbase assessment, so a ProcessUnity reviewer is one click from the full evidence trail.
## Trigger model
Syncs fire on the moments your process already has, not on a polling schedule:
```mermaid theme={null}
sequenceDiagram
participant PU as ProcessUnity
participant CB as Coverbase
PU->>CB: Push assessment (vendor, services, questionnaire)
CB->>CB: Run assessment: evidence, AI analysis, scoring, follow-ups
Note over CB: Analyst completes a risk-domain review
CB->>PU: Incremental sync: that domain's scores + review outcome
Note over CB: Assessment reaches SME review
CB->>PU: Status update
Note over CB: Assessment completed
CB->>PU: Full sync: all responses, overall scores, issues, attachments
```
The per-domain incremental sync means ProcessUnity reflects progress as each review lane (for example, security, compliance) finishes, not only at the end. The full sync on completion re-upserts everything and acts as the final reconciliation.
## Reliability
* **Positional field ordering, enforced.** ProcessUnity imports process fields by position, not name. The connector enforces the exact template field order on every record and holds empty positions explicitly. This is the most common source of silent data corruption in hand-built ProcessUnity integrations, eliminated structurally.
* **Idempotent by key.** Questionnaire-response pushes are row-level upserts keyed on ProcessUnity's response IDs; inbound replays match on ProcessUnity's assessment and vendor IDs. Re-deliveries and re-runs update in place.
* **Field limits handled.** ProcessUnity caps comment fields at 4,000 characters and truncates silently. Coverbase truncates proactively and appends the assessment link so reviewers can always reach the full content.
* **Full inbound audit trail.** Every payload ProcessUnity pushes is preserved with its request ID, byte count, and outcome, so any delivery question is answerable from the record rather than reconstructed from logs.
* **Best-effort outbound.** A ProcessUnity outage never blocks an analyst from completing a review; the completion-time full sync reconciles anything a transient failure missed.
* **User identity resolution.** Reviewers are identified to ProcessUnity by their ProcessUnity user ID, resolved by email against your tenant's own user report and cached, never by free-text names.
## Authentication and provisioning
The connector requests an OAuth2 access token from your ProcessUnity tenant using a web-service name and password together with a ProcessUnity user's credentials, stored per-organization in Coverbase's secrets manager (never in configuration or code). An admin enters them on the **ProcessUnity** card under **Configuration → External Integrations** (**ProcessUnity base URL**, **Service name**, **Service password**, **ProcessUnity username**, **ProcessUnity password**), and **Test connection** confirms that the tenant issues a token. Sandbox and production tenants are configured independently, and Coverbase teams routinely stand the integration up against the sandbox tenant first.
## In production
Bidirectional at scale: ProcessUnity pushes due-diligence and passive assessments (including multi-service vendors); Coverbase runs AI-driven analysis and vendor outreach, then syncs scores, domain reviews, issues, and attachments back, incrementally per risk domain and fully at completion.
Engagement requests flow from ProcessUnity into AI-autofilled intake drafts for analyst review; assessment starts select the matching Coverbase assessment plan from fourteen ProcessUnity assessment types; results and status updates flow back per type, so parallel assessments of different types never collide on the shared record.
## Onboarding checklist
What the integration needs from your team, typically stood up sandbox-first in a few weeks:
1. ProcessUnity web-service credentials and an integration user for sandbox and production tenants.
2. The import templates in your tenant that Coverbase will write to (your ProcessUnity admin creates these from Coverbase-provided field lists; their tenant-specific IDs are configured during onboarding).
3. Your assessment-type vocabulary, mapped to Coverbase assessment plans.
4. A user report or directory export so reviewer identities resolve to your ProcessUnity user IDs.
For the generic inbound surface these flows build on, see the [Import API](/import-api). For what to expect during delivery, see [onboarding](/integrations/onboarding).
# RapidRatings
Source: https://docs.coverbase.com/integrations/guides/rapidratings
Bring RapidRatings Financial Health Ratings for your portfolio into Coverbase: each vendor's rating is recorded, and a material drop becomes a Radar signal.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The RapidRatings connector is a licensed rating connector: you bring your own RapidRatings subscription, and Coverbase reads your portfolio with your credentials. It works like the [Black Kite integration](/user-guides/black-kite-monitoring). Ratings land on the vendor's **Certificates** tab under **Licensed Ratings**, and changes become [Radar](/products/supplier-radar) signals.
If a RapidRatings response does not have the shape Coverbase expects, the pull stops and the panel shows **The last sync failed** with the reason, instead of reading the response as an empty portfolio.
## What it does
* **Provisions monitoring once.** The first time you save credentials, Coverbase adds one RapidRatings source to Radar and one detector on it, named for a financial health rating drop. Both are created once. Archiving the source stops monitoring, and saving new credentials later does not bring it back.
* **Matches companies to vendors.** Each company in your portfolio is matched to a vendor by a match recorded on an earlier pull, then by its domain (walking up to the parent domain, never down), then by its exact legal name. A company that matches no vendor is skipped.
* **Records the rating.** Each pull records the matched vendor's Financial Health Rating (0 to 100).
* **Signals only on change.** A Radar item is raised only when a stored rating moved. The first pull is a baseline, so connecting a provider does not flood Radar.
## The detector
The detector starts enabled, alerting on a drop of 10 points or more between pulls. Edit it like any other Radar detector. It has three gates, and at least one must be set. A rating change alerts only when it passes every gate that is set. **Minimum drop** and **Alert below** take zero or more, in the provider's own units.
| Gate | Passes when |
| - | - |
| Minimum drop | The rating fell by at least this much since the last pull. |
| Alert below | The rating is below this value. |
| Grade worsened | The provider's grade or band got worse. |
Alerts go through the ordinary Radar path, so reassessment triggers and monitoring plan signal rules see them like any other signal.
## Authentication
RapidRatings uses OAuth 2.0 client credentials at `https://api.rapidratings.com/oauth/token`. Coverbase reads your portfolio from `/v1/portfolio/companies`.
1. Ask RapidRatings for API client credentials for your portfolio.
2. Add the vendors you want monitored to that portfolio.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **Rapid Ratings**.
2. Enter **Client ID**, **Client Secret**. The panel notes: "Saving the credentials adds a RapidRatings source to Radar for Financial Health Rating changes."
3. Click **Save**, then **Test connection**.
4. Open **Radar** to find the new source and its detector.
The panel never shows a stored secret again. **Remove** deletes the stored credentials; ratings already pulled stay.
## Related
Where licensed ratings show on a vendor.
Triaging the signals a rating change raises.
Letting a rating drop pull monitoring forward.
Coverbase's own outside-in rating, which needs no subscription.
# SafeBase
Source: https://docs.coverbase.com/integrations/guides/safebase
Pull vendor trust-center profiles and compliance documents from SafeBase automatically, so assessments start with the evidence vendors already publish.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Many vendors already publish their security posture through a **SafeBase** trust center: certifications, SOC 2 reports, policies, subprocessor lists. Coverbase pulls that published evidence automatically, so an assessment starts from what the vendor has already disclosed instead of opening with an email asking for it.
```mermaid theme={null}
flowchart LR
subgraph sb["Vendor's SafeBase trust center"]
profile["Security profile & certifications"]
docs["Compliance documents"]
end
subgraph cb["Coverbase"]
vendor["Vendor record"]
library["Document library"]
copilot["Assessment Copilot"]
end
profile -->|retrieved| vendor
docs -->|downloaded with provenance| library --> copilot
```
## What it does
* **Trust-center profile retrieval.** A vendor's SafeBase profile (products, posture data, published certifications) enriches the Coverbase vendor record automatically.
* **Document collection.** Compliance documents the vendor publishes are downloaded into the document library with their SafeBase provenance recorded, ready for [Assessment Copilot](/products/assessment-copilot) to analyze as evidence.
* **Less vendor friction.** Evidence the vendor already maintains in one place isn't re-requested over email. Outreach is reserved for what the trust center doesn't answer.
## Authentication and provisioning
SafeBase retrieval runs against the vendor's published trust center using SafeBase's API, with request signing handled by the connector. Gated trust centers that require an access grant follow the vendor's own approval flow.
## Onboarding checklist
Nothing to install: SafeBase retrieval participates in Coverbase's standard vendor enrichment and document collection. Where a vendor's trust center is access-gated, your team (or Coverbase, during an assessment) requests access through SafeBase as usual.
# SAP Ariba
Source: https://docs.coverbase.com/integrations/guides/sap-ariba
Inbound sync from SAP Ariba through the Integration Hub: supplier master data with qualification status links to your vendors and their approved supplier status, and sourcing events open intake requests.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The SAP Ariba connector is part of the [Integration Hub](/products/integration-hub). It is inbound only: SAP publishes no write endpoint for supplier master data, so Coverbase reads from Ariba and does not write back.
## What it does
| Ariba data | What happens in Coverbase |
| - | - |
| Supplier master data (Supplier Data API with Pagination) | Each supplier links to a vendor on tax ID or D-U-N-S number, or on website when nothing stronger disagrees, or waits in the steward queue. It links only to your organization's own vendors. Its qualification status sets the vendor's approved supplier status for Ariba: qualified, approved and preferred count as approved. |
| Sourcing events (Operational Reporting for Sourcing) | A draft intake request carrying the event's contract amount (or its planned spend when it has no contract amount, and an amount of zero counts), commodity and owner, shown to the Front Door as **Started From Procurement**. |
Supplier master records also appear on **Configuration → Vendor Master Data**, with the steward queue and the sync log.
## Authentication
Ariba issues a token from `https://api.ariba.com/v2/oauth/token` with client credentials in HTTP Basic, and every data call to `https://openapi.ariba.com` also carries your application's API key and your realm.
1. In the SAP Ariba developer portal, create an application with access to the **Supplier Data API with Pagination** and **Operational Reporting for Sourcing**.
2. Note the OAuth client ID and secret, the application key, and your realm name.
3. If you use a sourcing reporting view other than `SourcingProjectSourcingSystemView`, note its name.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **SAP Ariba**.
2. On **Authentication**, enter the **Client ID**, **Client secret**, **Application key** and **Realm**, and the **Sourcing reporting view** if you use your own.
3. Turn on **Open an intake request for each new requisition** to open intake requests from sourcing events.
4. Set **Sync Interval (Minutes)**, click **Save**, then **Test connection**.
5. Click **Sync now** and read the **Sync Log**. Work the **Steward Queue** for suppliers that did not match.
## Onboarding checklist
1. An Ariba test realm to connect first.
2. An application with both APIs, and its client ID, secret and application key.
3. Tax IDs or D-U-N-S numbers on your Ariba suppliers, so they link without a steward.
4. A steward to work the steward queue.
## Related
The sync log and the steward queue.
The two-way procure-to-pay connector.
Where a sourcing event is reviewed.
Another source of new suppliers.
# SecurityScorecard
Source: https://docs.coverbase.com/integrations/guides/securityscorecard
Bring SecurityScorecard scores for your portfolios into Coverbase: each vendor's score is recorded, and a material drop becomes a Radar signal.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The SecurityScorecard connector is a licensed rating connector: you bring your own SecurityScorecard subscription, and Coverbase reads your portfolio with your credentials. It works like the [Black Kite integration](/user-guides/black-kite-monitoring). Ratings land on the vendor's **Certificates** tab under **Licensed Ratings**, and changes become [Radar](/products/supplier-radar) signals.
## What it does
* **Provisions monitoring once.** The first time you save credentials, Coverbase adds one SecurityScorecard source to Radar and one detector on it, named for a security score drop. Both are created once. Archiving the source stops monitoring, and saving new credentials later does not bring it back.
* **Matches companies to vendors.** Each company in your portfolio is matched to a vendor by a match recorded on an earlier pull, then by its domain (walking up to the parent domain, never down), then by its exact legal name. A company that matches no vendor is skipped.
* **Records the rating.** Each pull records the matched vendor's Security Score (0 to 100).
* **Signals only on change.** A Radar item is raised only when a stored rating moved. The first pull is a baseline, so connecting a provider does not flood Radar.
## The detector
The detector starts enabled, alerting on a drop of 5 points or more between pulls. Edit it like any other Radar detector. It has three gates, and at least one must be set. A rating change alerts only when it passes every gate that is set. **Minimum drop** and **Alert below** take zero or more, in the provider's own units.
| Gate | Passes when |
| - | - |
| Minimum drop | The rating fell by at least this much since the last pull. |
| Alert below | The rating is below this value. |
| Grade worsened | The provider's grade or band got worse. |
Alerts go through the ordinary Radar path, so reassessment triggers and monitoring plan signal rules see them like any other signal.
## Authentication
SecurityScorecard issues an API key. Coverbase sends it as `Authorization: Token ` to `https://api.securityscorecard.io`, lists your portfolios from `/portfolios`, and reads each portfolio's companies.
1. In SecurityScorecard, create an API key for a user who can read your portfolios.
2. Note the ID of the portfolio to read, if you want only one.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **SecurityScorecard**.
2. Enter **API Token**, and optionally **Account ID** (a portfolio ID; leave it blank to read every portfolio the key can see). The panel notes: "Saving the key adds a SecurityScorecard source to Radar. Leave the account ID blank to read every portfolio."
3. Click **Save**, then **Test connection**.
4. Open **Radar** to find the new source and its detector.
The panel never shows a stored secret again. **Remove** deletes the stored credentials; ratings already pulled stay.
## Related
Where licensed ratings show on a vendor.
Triaging the signals a rating change raises.
Letting a rating drop pull monitoring forward.
Coverbase's own outside-in rating, which needs no subscription.
# ServiceNow
Source: https://docs.coverbase.com/integrations/guides/servicenow
Native integration with ServiceNow Vendor Risk Management: completed assessments, issues, and vendor documents land as VRM records your ServiceNow workflows already understand.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase integrates with ServiceNow's **Vendor Risk Management (VRM)** application natively and runs it in production today. Coverbase does the assessment work; results land in the same VRM tables your ServiceNow reporting, SLAs, and downstream workflows already consume, not in a side table or a file drop.
```mermaid theme={null}
flowchart LR
subgraph sn["ServiceNow"]
vrm_a["VRM assessments (sn_vdr_risk_asmt_assessment)"]
vrm_i["VRM issues (sn_vdr_risk_asmt_issue)"]
att["Attachments"]
end
subgraph cb["Coverbase"]
imp["Import API"]
work["AI assessment · scoring · review"]
exp["ServiceNow connector"]
end
sn -->|assessment context, vendor records| imp
imp --> work --> exp
exp -->|risk rating · state · recommendation| vrm_a
exp -->|one issue per finding| vrm_i
exp -->|vendor documents| att
```
## What flows
**Into ServiceNow, on assessment completion:**
| Coverbase | ServiceNow VRM destination |
| - | - |
| Assessment outcome and risk rating | VRM assessment record (rating, state) |
| Assessment summary and recommendation | VRM assessment record fields |
| Assessor and business owner | VRM assessment record references (by `sys_id`) |
| Document types received during the assessment | VRM assessment record |
| Each finding | A VRM issue record (level, rating, type, assignee, business owner), linked to the assessment, vendor, and engagement |
| Vendor-provided documents | Native attachments on the VRM assessment record |
**Out of ServiceNow:** assessment context (the VRM assessment, company, and engagement identifiers, assessor and business-owner references) arrives with the inbound push and is held on the Coverbase assessment, so every outbound write addresses the exact ServiceNow records it belongs to.
## Trigger model
```mermaid theme={null}
sequenceDiagram
participant SN as ServiceNow VRM
participant CB as Coverbase
SN->>CB: Push assessment context (assessment, company, engagement sys_ids)
CB->>CB: Run assessment: evidence, AI analysis, scoring, review
Note over CB: Assessment completed
CB->>SN: Update VRM assessment (rating, state, recommendation, documents received)
CB->>SN: Create one VRM issue per finding
CB->>SN: Upload vendor documents as attachments
```
## Reliability
* **Addressed by `sys_id`, never by name.** Every write targets ServiceNow records by their `sys_id` references captured at import time, so renames in either system never mis-route an update.
* **Validated identifiers.** Table names and `sys_id` values are validated against strict patterns before any request is constructed: no injection surface, no malformed writes.
* **Attachment limits respected.** ServiceNow's instance attachment size limit is enforced client-side before upload; oversized documents are reported rather than failed mid-transfer.
* **Best-effort completion sync.** A ServiceNow outage never blocks an analyst from completing an assessment; failed pushes are logged with the exact record identifiers for replay.
## Workflow actions
Beyond the VRM completion sync above, any [workflow](/integrations/workflow-engine) can write to ServiceNow once the connection is configured. In the action picker, the **ServiceNow record** group offers:
| Action | What it does |
| - | - |
| **Create** | Creates a record in the **ServiceNow table** you choose, from **Field mappings** of ServiceNow columns to text or variables, and links it to a Coverbase record (assessment, contract, engagement, finding, procurement, service, vendor or work queue item). **Match Existing Records On** reuses a record whose chosen fields already hold the same values instead of creating a duplicate. |
| **Update** | Updates the ServiceNow record linked to a Coverbase record. |
| **Create one per issue or finding** | Creates one record for each unresolved issue on the assessment, or for each finding attached to it, filterable by finding status, severity and source. An **Idempotency column** stops an interrupted run from creating duplicates. |
| **Send custom request** | Sends a `POST`, `PATCH` or `PUT` with a JSON payload you write to an instance-relative API path, with optional query parameters and value translations. |
| **Upload documents** | Uploads assessment supporting documents, the triggering document, or documents attached to a questionnaire submission as ServiceNow document records. |
Each linked record raises `ServiceNowRecord.Created`, `ServiceNowRecord.Updated` or `ServiceNowRecord.Deleted`, and a per-issue run ends with `ServiceNowSync.Completed`, so later steps and your [webhooks](/integrations/webhooks#event-catalog) can react. For each action step by step, see [ServiceNow workflow actions](/user-guides/servicenow-workflow-actions).
## Authentication and provisioning
An admin configures the connection self-serve on the **ServiceNow GRC** card under **Configuration → External Integrations**: the **ServiceNow base URL**, and either **Basic authentication** (a dedicated integration user's username and password) or **OAuth 2.0 (client credentials)** (a client ID and secret from the ServiceNow Application Registry). **Test connection** confirms the credentials, and **Save ServiceNow Configuration** stores them per organization in Coverbase's secrets manager. The integration identity needs write access to the tables your workflows write to (for VRM, the assessment and issue tables) and the attachment API, a scoped role your ServiceNow admin controls.
## In production
Runs its third-party risk program in Coverbase with ServiceNow VRM as the downstream system of record: completed assessments update the VRM assessment record, every finding lands as a VRM issue routed to the right business owner, and vendor evidence documents attach directly to the ServiceNow record, with no swivel-chair re-entry between the two systems.
## Onboarding checklist
1. A ServiceNow integration user or OAuth client with write access to the VRM assessment and issue tables and the attachment API, for your sub-production instance first.
2. The VRM field choices your process uses (issue types, ratings, states), so Coverbase maps outcomes onto your configured values.
3. The inbound push from ServiceNow (or an initial bulk load through the [Import API](/import-api)) carrying the assessment and vendor `sys_id` references.
ServiceNow can also receive Coverbase [webhooks](/integrations/webhooks) for real-time eventing outside VRM, for example to drive ITSM tickets from assessment lifecycle events. See [end-to-end workflows](/integrations/end-to-end-workflows).
# ServiceNow IRM
Source: https://docs.coverbase.com/integrations/guides/servicenow-irm
Push Coverbase findings as GRC issues and vendors as risks into ServiceNow Integrated Risk Management through the Table API, and read each record's state back, through the Integration Hub.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The ServiceNow IRM connector is part of the [Integration Hub](/products/integration-hub). It writes Coverbase findings to GRC issues (`sn_grc_issue`) and vendor risk to risks (`sn_risk_risk`) through the Table API, and reads each record's state back. It is separate from the [ServiceNow VRM and ITSM integration](/integrations/guides/servicenow), which creates records from workflows.
## What it pushes
* **Findings as issues**: every open finding that has a vendor, plus every finding already pushed, so a closure reaches ServiceNow IRM too.
* **Vendor risk**: every vendor with a residual or inherent risk level, plus every vendor already pushed.
Each record is created the first time and updated after that, and only when one of its mapped values changed. Coverbase keeps a link from each Coverbase record to the ServiceNow IRM record, which the sync log shows.
| Coverbase value | Issues (findings) | Risks (vendors) |
| - | - | - |
| **Title** | The finding's title | The vendor's name followed by "third party risk" |
| **Description** | The finding's text | |
| **Severity** | The finding's severity level | |
| **Status** | The finding's status | |
| **Vendor** | The vendor's name | The vendor's name |
| **Due date** | The remediation due date | |
| **Residual risk**, **Inherent risk**, **Risk tier**, **Approval status** | | The vendor's levels and status |
| **Open findings** | | How many open findings the vendor has |
| **Coverbase reference** | The finding number | The vendor's Coverbase ID |
| **Coverbase link** | A link to the finding | A link to the vendor |
Every value is written as text. A value with a blank target is not written.
## Status read back
After each push, Coverbase reads the `state` of every record it holds, by display value, in batches of 100, and shows it on the record link. It does not change the finding in Coverbase.
## Authentication
ServiceNow IRM uses OAuth 2.0 client credentials at `/oauth_token.do`.
1. In ServiceNow, create an OAuth API endpoint for external clients with the client credentials grant, and note the client ID and secret.
2. Give the integration user access to create, update and read the issue and risk tables.
3. If you use tables other than `sn_grc_issue` and `sn_risk_risk`, note their names.
## Set up in Coverbase
1. Open **Configuration → External Integrations** and click **ServiceNow IRM**, or open it from the **GRC and ERM** category of the Integration Hub.
2. On **Authentication**, enter the **Instance URL**, **Client ID** and **Client Secret**. Under **ServiceNow Tables**, change the **Issue Table** and **Risk Table** if you use your own.
3. Turn on **Push findings and vendor risk to ServiceNow IRM**, set the **Sync Interval (Minutes)**, click **Save**, then **Test connection**.
4. On **Field Mappings**, check the column for each value. The defaults write the issue title to `short_description`, its description to `description`, its due date to `due_date` and its reference to `correlation_id`, and the risk title to `name`. **Save mappings**.
5. Click **Sync now** and read the **Sync Log**.
## When a response is not what Coverbase expects
The Table API silently drops a column the table does not have, so every write asks for the mapped columns back, and a write that dropped one fails that record with the reason in the sync log.
If a create succeeds in the provider but Coverbase fails to save its link to the new record, the next sync creates a second record instead of updating the first. Remove any duplicate it leaves in the provider.
## Related
Field mappings and the sync log.
Building your own sync on the API instead.
The findings pushed as issues.
How the credentials are stored.
# Slack
Source: https://docs.coverbase.com/integrations/guides/slack
Connect Coverbase's Slack app to your workspace, let requesters ask for a new vendor in a direct message to the app, and route Coverbase events into Slack channels with webhooks.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase ships a Slack app that installs into your workspace through Slack's own authorization flow. Once connected, Coverbase can reach people in your workspace by direct message, matched to their Slack account by email.
Coverbase notifications (assignments, reviews, alerts) are delivered in the app and by email, not through the Slack app. The Slack app sends the test message below and, for organizations with the third-party lifecycle features, the [Intake Agent](#vendor-requests-in-slack)'s replies. To get Coverbase events into Slack channels, use [webhooks](#channel-based-patterns).
```mermaid theme={null}
flowchart LR
subgraph cb["Coverbase"]
test["Test message"]
end
subgraph slack["Your Slack workspace"]
dm["Direct message to the right person"]
end
test -->|matched by email| dm
```
## What it does
* **Installed by you, scoped by Slack.** An admin connects the app from the **Slack** card on the **Configuration → External Integrations** page with **Connect to Slack**. Slack's standard OAuth flow runs, so no credentials are entered in Coverbase and your workspace admins see and control exactly what the app can do.
* **Direct messages to the right person.** Coverbase resolves a recipient to their Slack identity by email. **Send test message** sends a message to the Slack account matching your own signed-in email, so you can confirm the match before relying on it.
* **Test, reauthorize, disconnect.** **Test connection** asks Slack to confirm the workspace, **Reauthorize Slack** repeats the authorization, and **Disconnect** removes the saved connection.
* **Rate-limit aware.** The connector honors Slack's retry-after signals and distinguishes transient failures from authorization problems.
## Vendor requests in Slack
With the [Intake Agent](/user-guides/intake-agent)'s Slack channel turned on, a requester sends the Coverbase app a direct message, or mentions it in a channel, describing the vendor they need. The agent answers in a direct message, asks only for what is missing, and opens an intake request. It accepts requests only from people whose confirmed Slack address belongs to an active member of your organization.
The channel needs the app to read direct messages and mentions. An app installed before the Intake Agent was available lacks that permission. The Intake Agent page then shows **Needs reinstall**, and **Reauthorize Slack** grants it.
## Channel-based patterns
For channel notifications and richer routing (a #vendor-risk feed, per-team channels), pair Coverbase [webhooks](/integrations/webhooks) with a Slack workflow or a small handler you control. The webhook carries the event type and affected object, so the routing logic stays yours.
## Onboarding checklist
1. A workspace admin connects the Coverbase Slack app (OAuth, self-serve).
2. Confirm user emails match between Coverbase and Slack, because email is how Coverbase finds each person in Slack. **Send test message** checks it for you.
3. For notifications in Slack today, register a webhook and route its events into the channels you choose.
# Snowflake
Source: https://docs.coverbase.com/integrations/guides/snowflake
Share your third-party risk tables into your own Snowflake account on a schedule, authenticated with a key pair, with a current view beside every table.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A Snowflake destination is part of [warehouse data share](/products/warehouse-data-share). Coverbase connects through the Snowflake SQL API with key-pair authentication, creates one table per contract table on the first sync, and keeps a `
_current` view beside each.
## Prepare Snowflake
1. Create a key pair. Keep the private key (PEM) for Coverbase, and set the public key on the Snowflake user as `RSA_PUBLIC_KEY`.
2. Give the user a role with:
* `USAGE` on the warehouse, the database and the schema;
* `CREATE TABLE` and `CREATE VIEW` on the schema.
3. Use a schema of its own, so Coverbase's tables and views do not mix with others.
```sql theme={null}
CREATE ROLE coverbase_share;
GRANT USAGE ON WAREHOUSE reporting_wh TO ROLE coverbase_share;
GRANT USAGE ON DATABASE risk TO ROLE coverbase_share;
GRANT USAGE ON SCHEMA risk.coverbase TO ROLE coverbase_share;
GRANT CREATE TABLE, CREATE VIEW ON SCHEMA risk.coverbase TO ROLE coverbase_share;
CREATE USER coverbase_share_user DEFAULT_ROLE = coverbase_share RSA_PUBLIC_KEY = '';
GRANT ROLE coverbase_share TO USER coverbase_share_user;
```
The names are examples; use your own.
## Add the destination in Coverbase
1. Open **Configuration → Data Share** and click **Add destination**.
2. Choose **Snowflake**, give it a **Name**, and choose **Hourly** or **Daily**.
3. Enter the **Account**, **User**, **Role**, **Warehouse**, **Database** and **Schema**, paste the **Private Key (PEM)**, and add the **Key passphrase** if the key has one.
4. Click **Add destination**, then **Test connection**, then **Sync now**.
After saving, the card shows the key's fingerprint as a hint. The private key is never shown again. Archiving the destination deletes it.
## What lands in Snowflake
* One table per contract table, created on the first sync. A column the contract adds later is added to the table.
* Each sync appends the rows that changed, stamped with `_cb_synced_at`.
* A `
_current` view per table keeps the newest version of each row. For the `services` snapshot table, it keeps only the latest run.
Point Power BI or Tableau at the `_current` views. The tables and their columns are listed under **Table Contract** on the Data Share page.
## Related
Run logs, pausing and the table contract.
The BigQuery destination.
The S3 destination.
How the private key is stored.
# Workday Strategic Sourcing
Source: https://docs.coverbase.com/integrations/guides/workday-strategic-sourcing
Procurement-driven intake: Workday Strategic Sourcing pushes suppliers into Coverbase, which enriches, tiers, and assesses them automatically.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase integrates with **Workday Strategic Sourcing (WSS)** in production today. The sourcing event is the trigger: when procurement advances a supplier in WSS, the supplier record flows into Coverbase, which enriches the vendor with AI, ingests the supplier's uploaded documents, maps procurement's classification onto your risk tiers, and, when a review is due, launches the assessment automatically. Security review keeps pace with procurement without anyone re-keying data.
```mermaid theme={null}
flowchart LR
subgraph wss["Workday Strategic Sourcing"]
supplier["Supplier record"]
docs["Supplier documents"]
end
subgraph cb["Coverbase"]
imp["Import API"]
enrich["AI vendor enrichment"]
tier["Tier & risk-level mapping"]
assess["Assessment (when due)"]
end
supplier -->|push on sourcing event| imp
imp --> enrich --> tier
docs -->|fetched by URL| assess
tier --> assess
```
## What flows
WSS pushes a supplier record into an org-scoped Coverbase import endpoint. From one push, Coverbase:
1. **Upserts the vendor and service**, keyed on WSS identifiers, so replays update rather than duplicate.
2. **Enriches the vendor with AI.** Company profile, description, and risk-relevant context are filled automatically rather than left blank for an analyst.
3. **Fetches the supplier's documents** from the URLs in the WSS record (security questionnaires, certifications, contracts) and stores them on the vendor with their WSS provenance recorded.
4. **Maps procurement's classification to your risk model.** WSS tier, data-classification, and volume answers translate to Coverbase custom fields and the vendor's risk level on your scale.
5. **Creates the assessment when one is due**, seeded with the fetched documents as supporting evidence, so the AI analysis starts from what procurement already collected. Pushes for suppliers not yet due for review update the record without launching redundant work.
6. **Activates the vendor and service** so they appear in your live portfolio immediately.
## Trigger model
```mermaid theme={null}
sequenceDiagram
participant WSS as Workday Strategic Sourcing
participant CB as Coverbase
WSS->>CB: Push supplier record (sourcing event)
CB->>CB: Upsert vendor + service, AI enrichment
CB->>WSS: Fetch supplier documents by URL
CB->>CB: Map tier + data classification to risk level
alt review is due
CB->>CB: Create assessment seeded with documents
else not yet due
CB->>CB: Update records only
end
```
## Reliability
* **Idempotent on WSS identifiers.** Re-pushed suppliers refresh the existing vendor and service; assessment creation is gated on review cadence, so procurement re-syncs never spawn duplicate assessments.
* **Validated before writes.** Malformed records are rejected with a field-level message and leave nothing behind.
* **Document provenance preserved.** Every document fetched from WSS is stored with its source recorded, so evidence in an assessment is always traceable to the procurement event that supplied it.
* **Graceful partial data.** A supplier record missing optional fields (documents, classification answers) still lands; the mapping fills what it has and leaves the rest to enrichment or the analyst.
## Authentication and provisioning
WSS pushes authenticate with an org-scoped Coverbase service-account API key, provisioned during onboarding and manageable through the [API keys](/api-reference/api-keys) surface. Document fetches use the URLs carried in the WSS record.
## In production
Runs procurement-driven vendor security review: every supplier advancing through Workday Strategic Sourcing lands in Coverbase already enriched, classified onto the company's vendor tiers, and, when due, under assessment with the supplier's own uploaded evidence attached. Incoming vendors and services activate immediately, so the security team's portfolio always matches procurement's reality.
## Onboarding checklist
1. A Coverbase service-account API key for the WSS push (provisioned during onboarding).
2. The WSS webhook or workflow step that pushes the supplier record at your chosen sourcing stage.
3. Your tier and data-classification vocabulary in WSS, mapped once to Coverbase risk levels and custom fields.
4. Assessment cadence rules: which tiers get assessed, and how often.
# What to expect during onboarding
Source: https://docs.coverbase.com/integrations/onboarding
How onboarding works, what Coverbase builds with you, what you configure yourself, and what security teams typically request.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Workflows in Coverbase are built in a no-code designer in the **Workflows** section of the dashboard, by your admins, at any time. Onboarding is a head start rather than a dependency: Coverbase sits with you and builds the first workflow set from your existing process documentation and integration targets, and hands it over as ordinary editable definitions.
There is no read-only stage and no configuration-only tier. Every trigger, condition, action and webhook Coverbase builds with you is one your admins can edit, clone, disable or replace, from the dashboard or the API, without involving Coverbase support. The same is true of control sets, questionnaires, statuses, approval options, risk domains, scales, custom fields and terminology. See [Configuring your data model](/user-guides/data-model-configuration).
## What you configure, and what we build with you
| You, self-serve | Coverbase, with you |
| - | - |
| Workflows: triggers, conditions, actions, review gates and approval routing | The first workflow set, built from your process documentation during onboarding |
| Control sets, questionnaires, clause sets, report templates | Advice on which library frameworks to fork for your regulatory profile |
| Custom fields, statuses, approval options, scales, risk domains, tags, terminology | - |
| Users, roles, user groups, out-of-office routing, SSO | - |
| API keys, webhooks, and self-serve integrations such as DocuSign, Slack, Jira, ServiceNow and ProcessUnity | - |
| - | Deep bidirectional connectors to a GRC, ERP or CLM system of record, where field mapping to your instance is genuine integration work |
## What security teams typically request
For integration architecture review, security teams typically request the following, all of which we provide on engagement:
Published in the [event catalog](/integrations/webhooks#event-catalog), and offered in the dashboard as the trigger picker in any workflow and the **Events** picker under **Configuration → Webhooks**.
One example payload for every subscribed event type. **Send test** on the **Webhooks** page previews the sample payload for any event type and can copy it as cURL.
The retry behavior, signature scheme, and verification approach described in the [Webhooks](/integrations/webhooks) reference.
The list of API endpoints used by the integration, scoped to the API key permissions required.
## Reference architectures
Several platforms have full deep-dive guides covering architecture diagrams, data mapping, trigger model, and what onboarding needs from your team:
* [ProcessUnity](/integrations/guides/processunity): bidirectional, in production
* [ServiceNow VRM](/integrations/guides/servicenow): in production
* [OneTrust](/integrations/guides/onetrust): in production
* [Workday Strategic Sourcing](/integrations/guides/workday-strategic-sourcing): in production
* [Aravo](/integrations/guides/aravo): triage-layer architecture
Pre-built reference architectures are available on request for:
* Ariba
* [Jira](/integrations/guides/jira)
* The major CLM platforms (Icertis, Ironclad, DocuSign CLM, Conga)
## What an integration delivery looks like
Platform integrations are stood up **sandbox-first**: the connector is configured and verified end to end against your platform's sandbox or sub-production tenant, including live read-back of what persisted, before production credentials are exchanged. A typical delivery runs:
1. **Credentials and scoping.** You provision a scoped integration identity (OAuth client, integration user, or API token) for the sandbox tenant; secrets are held in Coverbase's secrets manager, never in configuration.
2. **Mapping workshop.** Your field vocabulary (assessment types, ratings, statuses, custom attributes) is mapped once onto Coverbase's model, with tenant-specific identifiers recorded in configuration.
3. **Sandbox verification.** Full lifecycle runs against the sandbox, verified by reading the results back from your platform.
4. **Production cutover.** Production credentials swap in; the mapping carries over unchanged.
## Next steps
If you'd like to walk through how this maps to your specific environment, including which inbound integrations to prioritize, which webhook events to wire up first, and how onboarding sequences against your existing GRC and procurement stack, contact your Coverbase representative.
We can also share customer reference architectures from organizations with similar tooling profiles.
# Integration Workflows
Source: https://docs.coverbase.com/integrations/overview
How Coverbase integrates with the systems your organization already runs, end to end.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
This page describes how Coverbase integrates with the systems your organization already runs and how those integrations behave end to end. It's intended for security, integration, and procurement teams evaluating Coverbase as part of a broader third-party risk and vendor lifecycle stack.
The integration model is built around three layers: inbound API calls that bring data and commands into Coverbase, a workflow engine that orchestrates the work, and outbound webhooks that notify your downstream systems as work progresses.
## Architecture
External systems push data and commands into Coverbase. Procurement platforms create vendors, intake forms submit questionnaires, CMDBs sync service catalogs, and GRC tools start assessments. Each is a standard authenticated API call.
Once data lands, the workflow engine takes over. Triggers fire on object events, scheduled runs, or external invocation. Conditions branch the flow on risk score, tier, data class, jurisdiction, or contract value. Actions execute the work: create an assessment, send a portal to the vendor, raise review gates in parallel, and wait for their outcomes.
As workflows progress, Coverbase fires webhooks to endpoints you control. Webhooks carry the event type and the affected object, so ServiceNow, Jira, Slack, Ariba, Icertis, or your data warehouse can react in real time.
```mermaid theme={null}
flowchart LR
subgraph inbound["Your systems (inbound)"]
proc["Procurement (Ariba, Workday Strategic Sourcing)"]
grc_in["GRC platforms (ProcessUnity, Aravo)"]
cmdb["CMDB / intake forms"]
end
subgraph coverbase["Coverbase"]
api["Inbound API"]
engine["Workflow engine"]
objects["Vendors · Services · Assessments · Findings"]
out["Connectors & webhooks"]
end
subgraph outbound["Your systems (outbound)"]
sor["Systems of record (ProcessUnity, ServiceNow VRM, OneTrust)"]
itsm["Jira · Slack · Icertis"]
dw["Data warehouse"]
end
proc --> api
grc_in --> api
cmdb --> api
api --> engine --> objects --> out
out --> sor
out --> itsm
out --> dw
```
For the platforms Coverbase integrates with natively, including bidirectional GRC deployments running in production today, see the [platform-specific guides](/integrations/guides/processunity), and [integration patterns](/integrations/patterns) for the four shapes those integrations compose.
**Orchestration is yours to configure and to change.** Workflows are built in a no-code designer in the **Workflows** section of the dashboard: pick a trigger, add conditions, add actions, activate. Coverbase will build the first set with you during onboarding, and they are handed over as ordinary editable definitions rather than as locked configuration. After that, both the definitions and every running instance are reachable through the dashboard and the API, so you can interrupt, modify, or replace any step at any time. See [Configuring your data model](/user-guides/data-model-configuration).
## Public API surface
The public resource API covers these operations:
| Resource | Operations |
| - | - |
| Vendor | Create, list, get, update, read and refresh the fact sheet (`POST`/`GET`/`PATCH /v1/vendors`) |
| Service | Create + update under a vendor (`POST`/`PATCH /v1/vendors/{id}/services`) |
| User | Provision (create-or-get), list / look up by email, get, update role / deprovision (`POST`/`GET`/`PATCH /v1/users`) |
| Document | Upload, list, get, download, update, delete (`/v1/documents`) |
| Assessment | Create, get, archive (`POST /v1/assessments`, `GET`/`DELETE /v1/assessments/{id}`) |
| Finding | List, create, get, status-sync (`/v1/findings`) |
| Obligation | List, create, get, status-sync (`/v1/obligations`) |
| Radar | List and create events, list and triage alerts, list detectors and sources (`/v1/radar`) |
| Reassessment | Create, curate vendors, confirm, dismiss, run (`/v1/reassessments`) |
| Workflow | Run, schedule, list runs, get run with steps (`POST /v1/workflows/{name}/run`, `POST /v1/workflows/{name}/schedule`, `GET /v1/workflows/runs`) |
| Custom field | Discover definitions, read and write values (`/v1/custom-fields`) |
| Webhook | Create, list, update, delete, test, delivery history (`/v1/webhooks`) |
Bulk vendor/assessment loading is also available through the separate [Import API](/import-api). Control sets, statuses, tags, and scale levels are referenced **by ID** in these requests/responses; configure them in the dashboard.
The public API uses plural route names (`/v1/vendors`, `/v1/assessments`). Internal dashboard routes use singular nouns and are not part of the supported public surface.
## Where to go next
The four shapes every integration composes: inbound push, outbound sync, webhooks, file-based import.
How the ProcessUnity, ServiceNow, OneTrust, Workday Strategic Sourcing, and Aravo integrations work, with architecture diagrams.
Triggers, conditions, and actions. How orchestration logic is composed.
Three patterns for starting work in Coverbase from outside the UI.
Register endpoints, subscribe to event types, verify signatures, handle retries.
Full lifecycle walkthroughs for onboarding, parallel review, monitoring, and offboarding.
Gate outcomes, parallel domain-scoped SME reviews, multi-approver logic, and rework loops.
# Integration patterns
Source: https://docs.coverbase.com/integrations/patterns
The four integration shapes every Coverbase integration composes: inbound push, outbound sync, webhooks with workflows, and file-based import.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Every Coverbase integration, including the shipped [platform guides](/integrations/guides/processunity), composes the same four shapes. This page names them so your integration or platform team can map your systems onto them before the first architecture call.
```mermaid theme={null}
flowchart LR
subgraph external_in["Your systems"]
grc["GRC / TPRM platform"]
proc["Procurement / sourcing"]
files["Spreadsheets & exports"]
end
subgraph coverbase["Coverbase"]
import["Import API"]
engine["Workflow engine"]
store["Vendors · Services · Assessments · Findings"]
export["Export API & connectors"]
hooks["Webhooks"]
end
subgraph external_out["Your systems"]
sor["System of record"]
itsm["ITSM / ticketing"]
warehouse["Data warehouse"]
end
grc -->|push| import
proc -->|push| import
files -->|upload| import
import --> engine --> store
store --> export --> sor
store --> hooks --> itsm
hooks --> warehouse
```
## 1. Inbound push
Your system of record stays in charge and pushes into Coverbase: a procurement platform creates the vendor, a GRC platform starts the assessment, an intake form submits a questionnaire. Each push is a standard authenticated API call to an org-scoped endpoint.
What makes inbound pushes production-safe:
* **External IDs are the contract.** Every pushed record carries your system's identifier. Coverbase stores it and keys all matching on it, so a replayed delivery updates the existing record instead of duplicating it.
* **Validation before writes.** Required identifiers are checked before anything is persisted; a rejected payload leaves nothing behind. Rejections return `422` (malformed or missing fields) or `409` (the payload conflicts with existing records) with a message naming the offending field.
* **Replays are safe.** Redelivering the same payload refreshes the record from the latest data and never dispatches duplicate work: no second assessment run, no duplicate intake session, no re-imported attachments.
Used by the [ProcessUnity](/integrations/guides/processunity), [Workday Strategic Sourcing](/integrations/guides/workday-strategic-sourcing), and [Aravo](/integrations/guides/aravo) integrations, and by the generic [Import API](/import-api).
## 2. Outbound sync
Coverbase pushes results back into the system your auditors and downstream teams already look at: assessment outcomes, scores, review decisions, findings, and documents land as native records in the external platform.
What makes outbound syncs production-safe:
* **Native records, not exports.** Results are written to the platform's own object model (a ProcessUnity assessment record, a ServiceNow Vendor Risk assessment, a OneTrust risk), so downstream reporting works unchanged.
* **Idempotent upserts.** Every outbound record is keyed on an external ID. Re-running a sync updates in place; it never duplicates.
* **Best-effort by design.** An external platform outage never blocks your analysts: syncs are logged and retried, and a failed push never fails the assessment or the user's action that triggered it.
* **Platform limits handled proactively.** Field length caps, rate limits, and write-contention retries are handled inside the connector, not left to your team to discover.
Used by the [ProcessUnity](/integrations/guides/processunity), [ServiceNow](/integrations/guides/servicenow), and [OneTrust](/integrations/guides/onetrust) integrations.
## 3. Webhooks and workflows
For systems that want to *react* rather than hold a mirrored copy, Coverbase fires [webhooks](/integrations/webhooks) as objects change and the [workflow engine](/integrations/workflow-engine) orchestrates multi-step processes. External systems can also [trigger workflows](/integrations/triggering-workflows) directly.
This is the lightest-weight shape: no field mapping, no connector. An endpoint you control receives signed events and decides what to do.
## 4. File-based import
For platforms without a usable API, or for one-time migrations, Coverbase imports structured files (Excel, CSV) through per-format import specifications that parse your questionnaire or vendor export into Coverbase's control and question model. The same external-ID matching applies, so a file import and a later API integration reconcile onto the same records.
Used for bulk vendor loads, historical assessment migration, and questionnaire imports during onboarding. See the [Import API](/import-api).
## Composing the shapes
Real deployments combine shapes. A typical GRC coexistence deployment uses **inbound push** (the GRC platform starts assessments), **outbound sync** (results land back on the GRC record), and **webhooks** (ticketing and chat notifications along the way). See [end-to-end workflows](/integrations/end-to-end-workflows) for the full picture, and the [platform guides](/integrations/guides/processunity) for how each shipped integration composes them.
# Triggering workflows from external systems
Source: https://docs.coverbase.com/integrations/triggering-workflows
Three patterns for starting work in Coverbase from outside the UI.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The most common integration question is whether an external system can start work in Coverbase without anyone touching the UI. Yes. There are three patterns.
## Pattern 1: Create the object, let triggers handle the rest
Most workflows are bound to object events. The cleanest integration is to bring the object into Coverbase and let the workflow engine react.
Create the vendor with [`POST /v1/vendors`](/api-reference/vendors) (and its services with `POST /v1/vendors/{id}/services`), or load many at once through the [Import API](/import-api). Once a vendor is created, a workflow bound to the `Vendor.Created` trigger runs: conditions inspect the imported attributes, classify the vendor, and the workflow can launch an assessment, send a portal, and notify the internal owner with no UI interaction.
Use this pattern when the work maps naturally onto an object lifecycle. Use Pattern 2 or 3 when you need to start work explicitly against an existing object.
## Pattern 2: Explicitly start an assessment
When an external system needs to start an assessment on an existing vendor, for example a GRC tool beginning annual reassessment of a known vendor, it can call the assessments endpoint directly.
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/assessments" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162",
"control_set_ids": ["cbctst_9f4a1c0d7b2e4e9f8c1d2b3a4e5f6071"],
"service_ids": ["cbsvc_3c2b1a098f7e6d5c4b3a2918374655ab"],
"trigger_workflow": "annual-reassessment-flow"
}'
```
The `trigger_workflow` parameter is optional. If specified, that named workflow is started alongside the assessment (a `404 workflow_not_found` is returned if no workflow with that name exists for the org). See the [Assessments API](/api-reference/assessments) for the full request and response schema.
## Pattern 3: Invoke a named workflow directly
For cases that don't map cleanly to a single object event, for example sending the standard data privacy questionnaire to forty vendors and aggregating responses into a quarterly report, external systems can invoke a workflow by name and pass it parameters.
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/workflows/quarterly-privacy-sweep/run" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"input": {
"vendor_filter": { "tags": ["processes_pii"] },
"due_date": "2026-06-30"
}
}'
```
The workflow must be enabled and have a **Direct** entrypoint (the trigger reads **Running the workflow**), whose input is the `input` you send. A disabled workflow returns `409 workflow_disabled`. The response includes a `workflow_run_id` you can poll with `GET /v1/workflows/runs/{id}`, and `GET /v1/workflows/runs` lists runs. To run it later instead of now, call `POST /v1/workflows/{name}/schedule` with a `scheduled_for` Unix timestamp.
```json theme={null}
{
"workflow_run_id": "cbwr_a8f2c19e3d4b5e6f7a8b9c0d1e2f3a4b",
"workflow_name": "quarterly-privacy-sweep",
"status": "started",
"started_at": 1746576000,
"input": { "vendor_filter": { "tags": ["processes_pii"] }, "due_date": "2026-06-30" }
}
```
See the [Workflows API](/api-reference/workflows) for the full schema.
## Idempotency
`POST /v1/assessments`, `POST /v1/workflows/{name}/run` and `POST /v1/workflows/{name}/schedule` accept an `Idempotency-Key` header, as do `POST /v1/vendors`, `POST /v1/users` and `POST /v1/documents`. If the same key is replayed within 24 hours for that endpoint, the original response body is returned and no new run is started. Full behavior is documented in [API conventions → Idempotency](/conventions#idempotency).
```bash cURL theme={null}
curl -X POST "https://api.coverbase.app/v1/workflows/onboard-vendor/run" \
-H "Authorization: Bearer ak_live_xxx" \
-H "Idempotency-Key: ariba-req-7821" \
-H "Content-Type: application/json" \
-d '{ "input": {} }'
```
Use an identifier from the source system (a procurement request ID, a ticket number) as the idempotency key. That way retries from the source system are naturally deduplicated without extra bookkeeping on your side.
# Webhook delivery history
Source: https://docs.coverbase.com/integrations/webhook-deliveries
Inspect every webhook delivery attempt: status, response, and payload.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase records **every** webhook delivery attempt as an audit row. Whether the delivery came from a [domain-event fan-out](/integrations/webhooks#when-deliveries-happen), a workflow [`send_webhook` action](/integrations/workflow-engine#actions), or a manual [test](/api-reference/webhooks#test-a-webhook), there is one history record per attempt, including deliveries that were blocked by the [URL restrictions](/integrations/webhooks#url-restrictions).
Use the history to debug failing receivers, confirm a delivery happened, and monitor delivery health over time. The aggregate health of a subscription (`last_delivery_status`, `delivery_success_rate`, `delivery_count`) is also surfaced on the [webhook object](/api-reference/webhooks#response-fields).
## In the dashboard
Under **Configuration → Webhooks**, click a webhook's **Delivery history** button, or its **Health** value. The dialog lists each attempt with its **Event**, **Status**, **Response** (HTTP status and round-trip time) and **Attempted** time, newest first, with **View payload** to expand what was sent. The **Status** filter narrows the page you are looking at, and **Previous** and **Next** page through the rest.
## List delivery attempts
`GET /v1/webhooks/{webhook_id}/deliveries`
Returns the delivery attempts for one webhook, **newest first**, paginated. Org-scoped to the API key.
### Path parameters
The webhook subscription ID (`cbwh_...`).
### Query parameters
Page size. Clamped to the range `1`-`100` (values outside the range are clamped, not rejected).
Number of records to skip. Negative values are clamped to `0`.
### Example request
```bash cURL theme={null}
curl "https://api.coverbase.app/v1/webhooks/cbwh_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9/deliveries?limit=50&offset=0" \
-H "Authorization: Bearer ak_live_xxx"
```
```python Python theme={null}
import os
import requests
API_KEY = os.environ["COVERBASE_API_KEY"]
BASE_URL = "https://api.coverbase.app"
webhook_id = "cbwh_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9"
resp = requests.get(
f"{BASE_URL}/v1/webhooks/{webhook_id}/deliveries",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"limit": 50, "offset": 0},
timeout=30,
)
resp.raise_for_status()
print(resp.json())
```
### Example response
```json theme={null}
{
"data": [
{
"id": "cbwhd_9c7b4a2e8b3c1a4d9e7f2c5b6a8d1e3f",
"webhook_id": "cbwh_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9",
"event_id": "cbevt_8b3c1a4d9e7f2c5b6a8d1e3f9c7b4a2e",
"event_type": "Vendor.Created",
"status": "delivered",
"response_status": 200,
"response_time_ms": 142,
"error": null,
"payload": { "event_type": "Vendor.Created", "vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162" },
"attempted_at": 1747400001,
"created_at": 1747400001
}
],
"total": 1,
"limit": 50,
"offset": 0
}
```
### Response fields
The page of delivery attempts, newest first. Each item:
Delivery attempt ID (`cbwhd_...`).The subscription this attempt belongs to (`cbwh_...`).The shared event ID (`cbevt_...`) sent in the envelope and the `X-Coverbase-Event-Id` header.The event type the delivery was labeled with.One of `delivered`, `timeout`, `error`.The receiver's HTTP status code, or `null` if no response was received (timeout, connection error or blocked URL).Round-trip time in milliseconds, or `null` if no response was received.Error detail when `status` is `timeout` or `error` (for example, a blocked-URL message); otherwise `null`.The `data` object that was delivered for this attempt.Unix timestamp (seconds) when the attempt was made.Unix timestamp (seconds) when the audit row was written.
Total recorded attempts for this webhook, ignoring `limit`/`offset`. Page until `offset + len(data) >= total`.
The effective page size after clamping.
The effective offset after clamping.
### Delivery status values
| Status | Meaning |
| - | - |
| `delivered` | The receiver answered with a `2xx` status. `response_status` and `response_time_ms` are populated. |
| `timeout` | The request exceeded the 10-second per-attempt timeout. |
| `error` | The receiver answered with a non-`2xx` status (`response_status` is populated), a connection error occurred, or the URL was blocked by the [delivery-time SSRF re-check](/integrations/webhooks#url-restrictions). `error` carries detail. |
Every attempt is its own row. A delivery that timed out, lost its connection, or got a `408`, `429` or `5xx` answer is retried with the same `event_id`, up to six attempts in all, so the newest row for an `event_id` is where that delivery stands. Other non-`2xx` answers are recorded as `error` and not retried.
### Error responses
| Status | Body | When |
| - | - | - |
| 404 | `{"detail": {"code": "webhook_not_found", "message": "Webhook not found."}}` | The `webhook_id` does not exist or is not in the API key's org. |
### Pagination example
```bash Next page theme={null}
curl "https://api.coverbase.app/v1/webhooks/cbwh_d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9/deliveries?limit=50&offset=50" \
-H "Authorization: Bearer ak_live_xxx"
```
See [API conventions → Timestamps](/conventions#timestamps) for the epoch-seconds convention used by `attempted_at` and `created_at`.
# Webhooks
Source: https://docs.coverbase.com/integrations/webhooks
Delivery format, fan-out, signature verification, retries, and the event catalog.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Webhooks are the outbound half of an integration. This page documents how events are delivered, how to verify signatures, retry behavior, and the event catalog. To register, list, update, delete, test, or inspect the delivery history of a subscription, see the [Webhooks API](/api-reference/webhooks). For the audit trail of every attempt, see [Webhook delivery history](/integrations/webhook-deliveries).
Admins can do the same from the dashboard under **Configuration → Webhooks** (see the [Webhooks guide](/user-guides/webhooks)). Members see the list and the delivery history but cannot add, change, test or delete a webhook, in the dashboard or through the API. **Add webhook** takes an **Endpoint URL**, a **Signing secret** of at least 16 characters (shown only once), the **Events** to subscribe to, an optional **Description**, and an **Enabled** switch. Each row has **Send test**, **Delivery history**, **Edit** and **Delete** buttons, and the **Health** column shows the last delivery's status and the share of recorded attempts that got a `2xx` response.
## When deliveries happen
When a subscribed event occurs, Coverbase POSTs a JSON envelope to **every active webhook subscribed to that event type**. Deliveries originate from three sources, and all of them are recorded in [delivery history](/integrations/webhook-deliveries):
* **Domain-event fan-out**: a domain event (for example, a vendor is created) fans out to every subscription for that event type.
* **Workflow `send_webhook` action**: a workflow automation explicitly delivers its triggering event, either to the webhooks the action names or to every subscription for the event type. See [Workflow engine → Actions](/integrations/workflow-engine#actions).
* **Manual test**: the [test endpoint](/api-reference/webhooks#test-a-webhook), or **Send test** on the **Webhooks** page, sends a one-off delivery to a single subscription.
For one source event, the **same `event_id` is shared across all webhooks** in the fan-out. Receivers can use it to dedupe a fan-out and to correlate a multi-subscription delivery. A workflow `send_webhook` action generates its own `event_id` each time it runs, so an event delivered by both the fan-out and a workflow action arrives with two different IDs.
A webhook with no events selected receives nothing from the fan-out. Use that for an endpoint that should only receive what a workflow's `send_webhook` action addresses to it.
## Delivery format
A delivery is an HTTP `POST` with a JSON body in this exact envelope:
```json theme={null}
{
"event_id": "cbevt_8b3c1a4d9e7f2c5b6a8d1e3f9c7b4a2e",
"event_type": "Vendor.Created",
"occurred_at": 1747400000,
"data": { "event_type": "Vendor.Created", "vendor_id": "cbvndr_e448ba62882143f3ba0c140bb2e30162" }
}
```
| Field | Type | Notes |
| - | - | - |
| `event_id` | string | Shared delivery/event identifier (`cbevt_...`). The same value for every webhook in one fan-out. |
| `event_type` | string | The event type string (see the [event catalog](#event-catalog)). |
| `occurred_at` | integer | Unix timestamp in **seconds**, generated at send time. |
| `data` | object | Event-specific payload. For real events these are the catalog fields for that event type (and `data` echoes `event_type`). For a manual test, `data` is your custom `payload` (default `{"test": true}`). |
The envelope is exactly these four keys; there is no top-level `workflow_run_id` or any other field.
### Request headers
| Header | Value |
| - | - |
| `Content-Type` | `application/json` |
| `Coverbase-Signature` | Lowercase hex HMAC-SHA256 of the raw request body, keyed by your webhook `secret`. |
| `Coverbase-Timestamp` | Same value as `occurred_at`, in Unix seconds. |
| `X-Coverbase-Event-Id` | Same value as `event_id`. |
| `X-Coverbase-Event-Type` | Same value as `event_type`. |
## Signature verification
The signature is `HMAC-SHA256(secret, raw_request_body)` rendered as a lowercase hex string, sent in the `Coverbase-Signature` header. The key is the `secret` you registered with the subscription. Verify it against the **raw bytes** of the request body, before parsing JSON, with a constant-time comparison.
To reject replayed deliveries, compare `Coverbase-Timestamp` with your own clock and drop anything outside a window you choose (five minutes is typical). The same value is inside the signed body as `occurred_at`, so an attacker cannot change the header without the body no longer matching it.
```python Python theme={null}
import hashlib
import hmac
def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature_header)
# Flask example
from flask import Flask, request, abort
app = Flask(__name__)
WEBHOOK_SECRET = "whsec_a1b2c3d4e5f6a7b8c9d0e1f2" # the secret you registered
@app.post("/coverbase")
def receive():
raw = request.get_data() # raw bytes, do not re-serialize
sig = request.headers.get("Coverbase-Signature", "")
if not verify(raw, sig, WEBHOOK_SECRET):
abort(401)
event = request.get_json()
# dedupe on request.headers["X-Coverbase-Event-Id"] before handling
return "", 200
```
```javascript Node.js theme={null}
const crypto = require("crypto");
function verify(rawBody, signatureHeader, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(signatureHeader);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
// Express example (use express.raw so rawBody is the unparsed buffer)
app.post(
"/coverbase",
express.raw({ type: "application/json" }),
(req, res) => {
const sig = req.header("Coverbase-Signature") || "";
if (!verify(req.body, sig, process.env.WEBHOOK_SECRET)) {
return res.status(401).end();
}
const event = JSON.parse(req.body.toString("utf8"));
// dedupe on req.header("X-Coverbase-Event-Id") before handling
res.status(200).end();
},
);
```
## Delivery & retries
| Property | Value |
| - | - |
| HTTP method | `POST` |
| Connection timeout | 10 seconds per attempt |
| Retries | Up to 5 retries (6 attempts) after a timeout, a connection error, or a `408`, `429` or `5xx` response, waiting about 4 s, 16 s, 64 s, 4 min and 4 min between attempts. Any other non-`2xx` response, a blocked URL and a test event are not retried. Every attempt is recorded in [delivery history](/integrations/webhook-deliveries) |
| Ordering | Not guaranteed; deliveries are unordered |
| Duplicates | Possible: delivery is at-least-once. A retry after a timeout, or a worker that fails partway through a delivery, can send an event your receiver already processed. Every attempt carries the same `event_id` |
| Endpoint requirement | Public HTTPS endpoint (see [URL restrictions](#url-restrictions)) |
`event_id` is fixed when the event is raised and stays the same on every attempt. `occurred_at` and the `Coverbase-Timestamp` header are set again for each attempt, so a retry passes a receiver's replay window. Make your receiver **idempotent**: dedupe on `X-Coverbase-Event-Id` and process the same event id at most once. Respond with a `2xx` within 10 seconds. Retries cover a short outage, about 10 minutes from the first attempt. After a longer one, use [delivery history](/integrations/webhook-deliveries) to see which events never reached you and read the affected records back through the API.
### Source IP
Coverbase does **not** publish a fixed egress IP range for outbound webhook deliveries. Authenticate the sender by **HMAC signature verification** (see [Signature verification](#signature-verification)), not by source IP. The compute fleet is autoscaled and the public IPs that originate deliveries change frequently.
If you operate behind a network perimeter that requires a static allow-list, route deliveries through a customer-controlled HTTPS proxy with a stable egress IP and forward to the real receiver after re-verifying the signature.
## Delivery history retention
Every delivery attempt is recorded in [delivery history](/integrations/webhook-deliveries) for **90 days**. Older rows are deleted by a daily background job; the API still serves the window inside retention via `GET /v1/webhooks/{id}/deliveries`. Capture deliveries you need beyond that window from your receiver side at delivery time.
## URL restrictions
Webhook URLs must be **public HTTPS endpoints**. A URL is rejected at create/update time (`400 invalid_url`) if it is not HTTPS, carries credentials, uses a non-standard port, or resolves to a private, loopback, link-local, or metadata address (for example, `169.254.169.254`).
The same check is **re-applied with DNS resolution at delivery time**, and the delivery connects only to an address that check approved, with TLS still verifying the endpoint's own hostname. A hostname repointed to an internal address after registration, or one that answers the check and the connection differently (DNS rebinding), is still blocked. A delivery blocked this way is recorded with status `error` in [delivery history](/integrations/webhook-deliveries).
## Event catalog
These are the **only** values valid in a subscription's `events` array and the only event types emitted. The `events` field is strictly validated against this set; see the [behavior change](#strict-event-type-validation) below. Use the exact, case-sensitive strings. The same list is what the **Events** picker on the **Webhooks** page offers.
| `event_type` | `data` fields |
| - | - |
| `Assessment.Created`, `Assessment.Updated`, `Assessment.Deleted` | `assessment_id`; `.Updated` adds `field_diffs` |
| `Assessment.ManualHandoffRequested` | `assessment_id`, `work_queue_item_id` |
| `Commitment.Created`, `Commitment.Updated`, `Commitment.Deleted` | `commitment_id`; `.Updated` adds `field_diffs` |
| `Contract.Created`, `Contract.Updated`, `Contract.Deleted`, `Contract.Expired` | `contract_id`; `.Updated` adds `field_diffs` |
| `DarkWebExposure.Created`, `DarkWebExposure.Updated`, `DarkWebExposure.Deleted` | `dark_web_exposure_id`; `.Created` and `.Updated` add the [dark web exposure payload](/api-reference/webhooks#dark-web-exposure-payload); `.Updated` adds `field_diffs` |
| `Engagement.Created`, `Engagement.Updated` | `engagement_id`; `.Updated` adds `field_diffs` |
| `Finding.Created`, `Finding.Updated`, `Finding.Deleted` | `finding_id`; `.Updated` adds `field_diffs` |
| `IntakeSession.Created`, `IntakeSession.Submitted`, `IntakeSession.Updated`, `IntakeSession.Deleted` | `intake_session_id`; `.Updated` adds `field_diffs` |
| `Obligation.Created`, `Obligation.Updated`, `Obligation.Deleted` | `obligation_id`; `.Updated` adds `field_diffs` |
| `OrgIntake.Disabled` | `removed_questionnaire_id` |
| `OrgIntake.QuestionnaireRemoved` | `questionnaire_id`, `intake_disabled` (bool) |
| `Procurement.Created`, `Procurement.Updated`, `Procurement.Deleted` | `procurement_id`; `.Updated` adds `field_diffs` |
| `QuestionnaireResponse.Created`, `QuestionnaireResponse.Updated` | `questionnaire_response_id`; `.Updated` adds `field_diffs` |
| `RadarCase.Created`, `RadarCase.Updated`, `RadarCase.Deleted` | `radar_case_id`; `.Updated` adds `field_diffs` |
| `RadarDetectorResult.Created`, `RadarDetectorResult.Updated`, `RadarDetectorResult.Deleted` | `radar_detector_result_id`; `.Updated` adds `field_diffs` |
| `RadarEvent.Created`, `RadarEvent.Updated`, `RadarEvent.Deleted` | `radar_event_id`; `.Updated` adds `field_diffs` |
| `RadarSignal.Created`, `RadarSignal.Updated`, `RadarSignal.Deleted` | `signal_id`; `.Updated` adds `field_diffs` |
| `Reassessment.Created`, `Reassessment.Updated`, `Reassessment.Deleted` | `reassessment_id`; `.Updated` adds `field_diffs` |
| `Review.Created`, `Review.Updated`, `Review.Deleted` | `review_id`; `.Updated` adds `field_diffs` |
| `RiskRegisterEntry.Created`, `RiskRegisterEntry.Updated`, `RiskRegisterEntry.Deleted` | `risk_id`; `.Updated` adds `field_diffs` |
| `ScreeningMatch.Created`, `ScreeningMatch.Updated`, `ScreeningMatch.Deleted` | `screening_match_id`; `.Updated` adds `field_diffs` |
| `Service.Created`, `Service.Updated`, `Service.Deleted` | `service_id`; `.Updated` adds `field_diffs` |
| `MonitoringRecord.Created`, `MonitoringRecord.Updated`, `MonitoringRecord.Deleted` | `monitoring_record_id`; `.Updated` adds `field_diffs` |
| `MonitoringRecord.ScopingDue` | `monitoring_record_id`, `vendor_id`, `verdict`, `closes_at_planned` (nullable) |
| `MonitoringRecordEntry.Created`, `MonitoringRecordEntry.Updated`, `MonitoringRecordEntry.Deleted` | `monitoring_record_entry_id`; `.Updated` adds `field_diffs` |
| `ServiceNowRecord.Created`, `ServiceNowRecord.Updated`, `ServiceNowRecord.Deleted` | `servicenow_record_link_id`; `.Updated` adds `field_diffs` |
| `ServiceNowSync.Completed` | `assessment_id`, `servicenow_table`, `created_record_count` |
| `Sla.Created`, `Sla.Updated`, `Sla.Deleted` | `sla_id`; `.Updated` adds `field_diffs` |
| `SupplierDiversityRecord.Updated` | `supplier_diversity_record_id`, plus the [supplier profile fields](#supplier-profile-events) |
| `SupplierLegalEntityAssignment.Assigned`, `SupplierLegalEntityAssignment.Rejected` | `supplier_legal_entity_assignment_id`, `entity_code` (nullable), plus the [supplier profile fields](#supplier-profile-events) |
| `SupplierSite.Created`, `SupplierSite.Updated`, `SupplierSite.Deleted` | `supplier_site_id`, plus the [supplier profile fields](#supplier-profile-events) |
| `SupplierTaxRegistration.Updated` | `supplier_tax_registration_id`, plus the [supplier profile fields](#supplier-profile-events) |
| `SupplierUpdateRequest.Submitted` | `supplier_update_request_id`, plus the [supplier profile fields](#supplier-profile-events) |
| `Vendor.Created`, `Vendor.Updated`, `Vendor.Deleted` | `vendor_id`; `.Updated` adds `field_diffs` |
| `VendorBankAccount.Created`, `VendorBankAccount.Updated`, `VendorBankAccount.Retired` | `vendor_bank_account_id`, plus the [supplier profile fields](#supplier-profile-events) |
| `VendorContact.Updated` | The [supplier profile fields](#supplier-profile-events) |
| `VendorDocument.Created`, `VendorDocument.Updated`, `VendorDocument.Deleted` | `vendor_document_id`; `.Updated` adds `field_diffs` |
| `WorkflowRun.Created` | `workflow_run_id`, `input` |
| `WorkflowRun.Updated`, `WorkflowRun.Deleted`, `WorkflowRun.Completed`, `WorkflowRun.Failed` | `workflow_run_id`; `.Updated` adds `field_diffs` |
| `WorkQueueItem.Created`, `WorkQueueItem.Completed`, `WorkQueueItem.Updated`, `WorkQueueItem.Deleted` | `work_queue_item_id`; `.Updated` adds `field_diffs` |
`*.Updated` events carry a `field_diffs` object mapping each changed field to its `{ "old_value", "new_value" }`, so a status change arrives as `Vendor.Updated` (or `Assessment.Updated`, `Review.Updated`, and so on) with the status field in `field_diffs`. A soft-archive (`is_archived` → `true`) surfaces as `*.Deleted`, not `*.Updated`.
A **radar alert** is a `RadarDetectorResult`: subscribe to `RadarDetectorResult.Created` to be notified of new alerts and `RadarDetectorResult.Updated` (whose `field_diffs` will include `is_dismissed`) for triage activity. A **signal** is a `RadarSignal`. See the [Radar](/api-reference/radar) and [Reassessments](/api-reference/reassessments) APIs.
### Supplier profile events
The `VendorBankAccount`, `VendorContact`, `SupplierSite`, `SupplierTaxRegistration`, `SupplierDiversityRecord`, `SupplierUpdateRequest` and `SupplierLegalEntityAssignment` events describe changes to a supplier's profile. Besides their own ID, each carries:
| Field | Notes |
| - | - |
| `change_event_id` | The profile change this event reports. Every webhook that receives the change gets the same value, so use it as your idempotency key. Nullable. |
| `vendor_id` | The supplier the change belongs to. Nullable. |
| `entity_id` | The ID of the record that changed, such as the bank account or site. Nullable. |
| `sensitivity` | `normal`, or `sensitive` for a fraud-relevant change. Bank account changes are always `sensitive`. |
| `actor_type` | Where the change came from: `supplier_portal`, `internal_user`, `api` or `system`. |
| `diff`, `snapshot` | What changed, and the saved record. Account and tax numbers appear only as their last four characters. |
A `sensitive` change fires its event only after a reviewer approves it, not when it is requested.
`SupplierUpdateRequest.Submitted` and `VendorContact.Updated` can be subscribed to, but nothing sends them yet. What a supplier changes in answer to an update request arrives as the record events above.
All IDs are opaque prefixed strings (for example, `cbvndr_...`, `cbqsrw_...`); see [API conventions → IDs](/conventions#ids). Every event's `data` also echoes its own `event_type`.
`webhook.test` is a valid value only for the [test endpoint's](/api-reference/webhooks#test-a-webhook) `event_type` field. It is **not** a subscribable event type; it will be rejected if used in a subscription's `events` array.
### Strict event-type validation
**Breaking change.** `events` is now strictly validated against the catalog above. Previously any free-form string was accepted. A `POST /v1/webhooks` or `PATCH /v1/webhooks/{id}` whose `events` contains a value not in the catalog now fails with `422 invalid_event_types`. Integrations that registered non-canonical strings (for example, lowercase `vendor.created`) must switch to the exact catalog value (for example, `Vendor.Created`).
# Workflow engine
Source: https://docs.coverbase.com/integrations/workflow-engine
How triggers, conditions, and actions compose into orchestration logic.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A workflow is a sequence of triggers, conditions, and actions that runs against a primary object.
## Triggers
A trigger is the event that starts a workflow. Triggers fall into three groups.
A primary object is created, updated, or transitions state. Examples include a new vendor being created, an assessment moving to completion, a contract's term running out (`Contract.Expired`), or a finding being raised. Every trigger in the picker is an event in the [event catalog](/integrations/webhooks#event-catalog).
A workflow run is scheduled for a specific time. On a workflow's page, the **Run workflow** button offers **Schedule for later...**, and a **Run workflow** action inside another workflow can start its target now or at a later time. Pending runs are listed under **Scheduled** on the workflow's **History** tab, where each can be canceled. There is no recurring (cron-style) trigger: for a periodic review, use reassessment rules, which set each vendor's next assessment date from its risk level.
An external system explicitly invokes a workflow through the API. This is the integration path most relevant to procurement and GRC tooling.
See [Triggering workflows from external systems](/integrations/triggering-workflows) for the three patterns.
## Conditions
Conditions branch the flow. They evaluate fields on the primary object or its related objects.
The condition picker offers:
* IRQ score within a threshold range
* Vendor status, tier or tags
* Assessment status, assignee, recommendation, plan, risk type, inherent risk level or document collection mode
* Procurement status, reviewers and review status, and contract value
* An answer to a questionnaire question
* Which fields changed on the triggering record
* Whether work queue items are complete
* Whether the triggering record was opened by this workflow, so a chain only advances on the records it created
* Any built-in or [custom field](/api-reference/custom-fields) on the triggering record or a related record, through the same filter paths the dashboard uses. Attributes such as data classification, hosting model or jurisdiction are usually matched here.
The conditions on an automation are combined with **Match all** or **Match any**.
### Gate conditions
Four conditions exist specifically to express approval logic.
| Condition | What it evaluates | Typical use |
| - | - | - |
| **Contract value** | Total value of the contracts on a procurement against a threshold, with `greater than` and `less than or equal` operators | Delegation-of-authority routing: above the limit picks up the extra approver. Amounts are summed in the contracts' own currency and never converted; when they span two currencies the total counts as over the threshold, so the extra approver is always added |
| **Work queue item complete** | Whether the review work raised by this workflow run is finished, scoped to `self`, the vendor, or the whole run, with a **require all** toggle | Unanimous gates (`require all` on) and first-past-the-post gates (off). Vary the set of reviews you raise per tier to express a quorum |
| **Assessment recommendation** | The approval option selected on the assessment, matched against a set you choose | Route `Approve with policy exception` down a different path from `Approve` |
| **Reviewer present** | Whether a given reviewer already holds a review on the record | Avoid raising a duplicate gate on a re-triggered run |
See [Reviews, approvals and gates](/user-guides/reviews-and-approvals) for how these compose into all-of, any-of, threshold-based and sequential approval patterns.
## Actions
Actions execute work. The action picker groups them by the record they act on:
### Review gates and approvals
The **raise a review gate** action is how approval logic is expressed.
* **Scope.** A review attaches to an assessment, a contract or a procurement. Adding a risk domain makes it domain-scoped, and there is exactly one review per `(assessment, risk domain)` pair, so a domain cannot be gated twice by accident.
* **Parallel by default.** Raise several in one branch and they run at the same time, each with its own assignee, status, notes and outcome. Nothing serializes them.
* **Routing.** The assignee can be an individual or a user group. A group resolves through its own strategy at assignment time: every eligible member for an assign-to-all group, or the next person in the rotation for a round robin, skipping anyone inside an out-of-office window. Both the group and the resolved individual are stored. See [Assignment, delegation and out of office](/user-guides/assignment-and-delegation).
* **Work lands somewhere.** Each raised review mints a work queue item and notifies its assignee, so the gate appears on a person's Overview page rather than only on the record.
* **Idempotent on re-trigger.** A workflow legitimately revisits the same component many times across a reject, rework and resubmit cycle, so gate actions are keyed per run and can upsert onto an existing review instead of stacking duplicates.
### `send_webhook` action
The **Send webhook** action delivers the workflow's triggering event to [webhooks](/integrations/webhooks).
* By default the event type is the workflow's triggering event; an optional **event type override** changes the type the delivery is labeled with and, when no webhooks are named, which subscriptions are matched.
* An optional **`webhook_ids`** list names the exact webhooks to deliver to. Naming a webhook is the subscription decision: it receives the delivery whatever events it subscribes to. Omit it to fan out to every active subscription for the event type.
* A disabled or archived webhook receives nothing either way.
* One shared `event_id` is generated per action invocation, so a receiver can dedupe a multi-webhook fan-out, using the same idempotency model as the [domain-event fan-out](/integrations/webhooks#when-deliveries-happen).
Every delivery from this action is recorded in [delivery history](/integrations/webhook-deliveries). If there is no active webhook to deliver to, the step is skipped.
To start a workflow from outside the dashboard, run it by name through the API. See [Triggering workflows from external systems](/integrations/triggering-workflows).
# Replacing the assessment export
Source: https://docs.coverbase.com/mcp/assessment-exports
Map every column of the Consolidated Assessment Report export to the MCP call that returns it, with sample input, sample output, and prompts for building a GRC dashboard on top.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Teams building an internal GRC dashboard often start from the **Consolidated Assessment Report** export, then move to the MCP server so the data refreshes without anyone clicking **Export**. This page maps that spreadsheet column by column, so you can port a mapping instead of probing calls to find out what exists.
You do not need this page to ask questions about an assessment. Ask in plain language and the assistant picks the route. This is for when you are writing an integration and need to know which call returns which column.
## Column mapping
| Export column | MCP call |
| - | - |
| Assessment Name, Status, Assignee, Assessment Score | `query_assessments(kind="detail")`, and every `kind="search"` row |
| Assessment Outcome | `detail`, `summary`, `details_legacy`, and every `search` row |
| Residual Risk Score, Residual Risk Level | `detail`, `summary`, `details_legacy`, and every `search` row |
| Summary | `query_assessments(kind="summary")`. `detail` carries a preview |
| Notices | `summary` |
| Date Created, Initiated By, Run Counter | `detail` |
| Products, Services | `detail` |
| Policy Control Sets Count | `detail`, which also names the sets |
| Parsed Questionnaire Count, Parsed Policy Count | `detail`, as one **Parsed controls** line |
| Supporting Documents Count | `detail`, which also lists the documents |
| Inherent Risk Score, Inherent Risk Level | `detail`, under the vendor section |
| SLA stage timings, targets, and breaches | `detail` |
| Custom field columns | Any read that returns the assessment. See [custom fields](#custom-field-columns) |
| Errors | Not exposed. See [what is not exposed](#what-is-not-exposed) |
Every count column returns a number even when it is zero, because the export writes a number in every row. An omitted field would be indistinguishable from a count of none.
## The summary report
`kind="detail"` carries the opening 500 characters of the AI summary as a preview, then says so and names the call that returns the rest. `kind="summary"` returns the whole report.
### Input
```json theme={null}
{
"tool": "query_assessments",
"arguments": {
"kind": "summary",
"assessment_id": "cbqsrw_hub01"
}
}
```
### Output
```markdown theme={null}
# Assessment Summary: 2026 HubSpot, Inc. initial
**ID:** `cbqsrw_hub01` | https://dashboard.coverbase.app/assessments/cbqsrw_hub01
**Status:** Complete
**Outcome:** Conditionally Approve
**Recommendation status:** conditionally_approve
**Residual risk:** Moderate - score 38.24
**Assessment score:** 56.6%
**Assessment level:** Medium
**Inherent risk:** Level 3 - score 61.00
## Summary
## Decision Summary
Conditionally approve HubSpot for marketing automation.
## Key Business Risks
- Customer PII (names, emails, phone numbers) is processed in a multi-tenant CRM shared with other HubSpot customers, with logical separation only.
- No customer-managed encryption keys are offered on the current contract tier, so key rotation and revocation stay with the vendor.
## Required Conditions
1. Enforce SSO for all admin accounts by 2026-12-01.
2. Annual SOC 2 Type II on file.
## Follow-Ups
| Item | Owner | Due |
|---|---|---|
| SSO enforcement | IT | 2026-12-01 |
## Vendor Remediation Message
Please confirm SSO enforcement and share the SOC 2.
## Recommendation
Approve subject to MFA rollout across admin accounts.
## Notices
- SOC 2 expires in 30 days
```
The sections between `## Summary` and `## Recommendation` are whatever your workspace's summary prompt produces. The headings above are an example, not a fixed schema.
A summary whose underlying data was corrected after it was written is flagged as needing regeneration, so you do not publish prose that no longer matches the evaluations it describes.
### Paging a long report
Reports longer than one response can carry are truncated with a notice that names the next call:
```text theme={null}
_[Truncated: showing characters 0-20,000 of 26,400. Retrieve the rest with
query_assessments(kind="summary", assessment_id="cbqsrw_hub01", summary_offset=20000).]_
```
Pass `full_text=true` to raise the cap instead of paging.
## Mapping a whole portfolio
Do not call `kind="detail"` once per assessment. The outcome and the residual risk are on every `search` row, so a few hundred assessments map in one call per page.
### Input
```json theme={null}
{
"tool": "query_assessments",
"arguments": { "kind": "search", "limit": 50 }
}
```
### Output
```text theme={null}
Found 1 assessment(s):
- **2026 HubSpot, Inc. initial** (id: `cbqsrw_hub01`, status: Complete,
outcome: Conditionally Approve, vendor: cbvndr_hub score: 56.6%,
residual risk: Moderate - score 38.24)
```
Call `kind="summary"` only for the assessments whose narrative you need.
## Custom field columns
Custom field values come back with no extra parameter. They appear as a `## Custom Fields` section on `kind="detail"` and as an indented `_Custom:_ name=value` line under each `kind="search"` row.
Fields with no value set are omitted, so an assessment where the field was never filled in renders nothing at all. If a value is missing that you expect to be there, check the assessment in the app first: an empty field and an unreachable field look the same in the response.
`query_platform(kind="custom_fields", target_type="assessment")` lists the definitions, not the values. Use it to discover which fields exist, then read the values from the assessment itself.
## What is not exposed
**Errors** is the one export column with no MCP equivalent. It holds raw processing error payloads that can incidentally contain personal data, so it is not returned. Everything else in the export is mapped above.
## Scoring settings change what you get
Two settings under **Configuration → Scoring** change every read, matching which columns the export itself drops:
* **Residual risk tracking off**: residual risk is omitted everywhere, level and score alike.
* **Numerical scores off**: raw inherent and residual risk numbers are omitted and the named levels stay. The assessment score percent is unaffected.
If residual risk is missing from a response and you expect it, check that setting before opening a ticket.
## Prompts for this workflow
> We're replacing the Consolidated Assessment Report export with this connector. For assessment cbqsrw\_hub01, give me every field that export has: outcome, residual risk score and level, the full summary, and the counts.
The assistant reads `kind="detail"` for the decision and scope fields, then `kind="summary"` for the narrative, and tells you which columns have no equivalent rather than silently omitting them.
> Give me the complete written summary for the HubSpot assessment, not the preview. I need the decision summary, the required conditions, and the vendor remediation message.
Resolves the name to an assessment, then calls `kind="summary"`. If the report is long, it pages through and gives you the whole thing.
> List every completed assessment from this quarter with its outcome, residual risk level, and residual risk score, as a table I can load into a dashboard.
One `kind="search"` call per page carries all three fields, so this does not fan out into one call per assessment.
> Which assessments were conditionally approved, and what conditions did we attach to each?
The outcome is on the search rows, so the assistant filters there, then reads `kind="summary"` for the required conditions on only the matching assessments.
> I exported the Consolidated Assessment Report yesterday. Read the same assessments through the connector and tell me where the two disagree.
Useful as a one-off during migration. Expect residual risk to be absent if your workspace has residual risk tracking off, and expect Errors to have no equivalent.
> The ServiceNow ticket field isn't coming back for cbqsrw\_hub01. Is it set on that assessment?
Custom field values are returned automatically when set, so an absent value usually means an empty field rather than a missing route.
Every kind on every read dispatcher, and the parameters each one takes.
# Connecting clients
Source: https://docs.coverbase.com/mcp/connecting
Connect Claude Code, Claude.ai, Claude Desktop, Cursor, VS Code, Microsoft Copilot Studio, and other MCP clients to the Coverbase MCP server.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The exact connection flow depends on which client you're using. The general pattern is the same: point the client at the Coverbase MCP endpoint, complete the OAuth flow in your browser, and the tools become available in your session.
## Server endpoint
```text theme={null}
https://mcp.coverbase.app/mcp
```
The server speaks MCP over **Streamable HTTP**. On first connection your client opens a browser window so you can sign in to Coverbase and authorize access. Your permissions in Coverbase determine what the connected assistant can see and do.
## Choosing an authentication method
The server accepts two kinds of credential, and which one you want depends on whether a person is present at setup.
| | **OAuth 2.0** | **API key** |
| - | - | - |
| Setup | Browser sign-in on first connect | Paste a key into your client config |
| Best for | Desktop and IDE clients you use yourself | Headless pipelines, CI, containers |
| Identity | The signed-in user | Whoever the key was minted to act as |
| Access | Read/write, or narrower if the client asks | Read/write or read-only, fixed when the key is generated |
OAuth (PKCE, no client secret) is the default and the right choice for interactive clients. The rest of this page assumes it.
If a browser step is impossible, generate a long-lived key instead and send it as a bearer token. **This is the part that is easy to miss: a client configured with only a URL and no `Authorization` header will be answered with a `401` and pushed into the OAuth flow**, which is exactly what an API key exists to avoid.
In Coverbase, go to **Configuration → MCP Server** and generate a key under **API key**. It starts with `cb_mcp_` and is shown only once.
Two choices on that dialog decide what the key can do. **This key acts as** picks the identity behind it: yourself, a **service account** that needs no seat in your identity provider, or another user. **Read-only** withholds write permanently. If you are wiring up an automation that should only ever read, see [Programmatic read-only access](/mcp/permissions#programmatic-read-only-access).
This is a different page from **Configuration → API Keys**, which issues `ak_` keys for the [Coverbase REST API](/api-reference/api-keys). The two key types are not interchangeable: an `ak_` key will not authenticate against the MCP server.
Add an `Authorization` header to whichever config shape your client uses:
```bash Claude Code theme={null}
claude mcp add --transport http coverbase https://mcp.coverbase.app/mcp \
--header "Authorization: Bearer cb_mcp_YOUR_KEY"
```
```json Config file theme={null}
{
"mcpServers": {
"coverbase": {
"type": "streamable-http",
"url": "https://mcp.coverbase.app/mcp",
"headers": { "Authorization": "Bearer cb_mcp_YOUR_KEY" }
}
}
}
```
Two limits worth knowing before you build on this:
* **Key generation is restricted to organization admins.** If the button isn't there, ask an admin in your organization to generate one for you.
* **A key carries the access of the identity it acts as.** A key that acts as you or another user carries that person's role, re-checked against their live membership on every request, so if their role changes the key follows it, and if they leave the organization the key stops working. For an unattended pipeline, have an admin generate the key as the **Service account**, which does not depend on any individual. A key that acts as anyone but you is always read-only.
If your integration only needs to read and write Coverbase records, rather than drive an AI assistant, the [REST API](/api-reference/api-keys) is usually the better fit. It is built for non-interactive use, and its `ak_` keys can belong to a true service account.
## Claude Code
Add the Coverbase server with the HTTP transport:
```bash theme={null}
claude mcp add --transport http coverbase https://mcp.coverbase.app/mcp
```
Then start Claude Code, run `/mcp`, and choose **Authenticate** to complete OAuth sign-in in your browser. The Coverbase tools are available once the status shows connected.
Use `--transport http` for the remote Coverbase server. Without it, the CLI assumes a local stdio command and the connection will fail.
## Claude.ai
In Claude, open **Settings → Connectors**.
Click **Add custom connector**, name it `Coverbase`, and paste the server endpoint.
Click **Add**, then **Connect**. You'll be redirected to Coverbase to sign in, review the requested scopes, and approve.
Return to Claude. The Coverbase tools are now available in your conversations.
## Claude Desktop
Open Claude Desktop, go to **Settings → Connectors**, and click **Add custom connector**. Name it `Coverbase`, paste the server endpoint, and click **Add**. Click **Connect** and sign in to Coverbase when prompted.
## Cursor
In Cursor's settings, open **MCP → Add new server**, or add the server to `~/.cursor/mcp.json`:
```json theme={null}
{
"mcpServers": {
"coverbase": {
"type": "streamable-http",
"url": "https://mcp.coverbase.app/mcp"
}
}
}
```
Cursor handles the OAuth flow in your browser on first use.
## VS Code
VS Code supports MCP servers natively in **GitHub Copilot agent mode**. Add the server to your `settings.json`:
```json theme={null}
{
"mcp": {
"servers": {
"coverbase": {
"type": "streamable-http",
"url": "https://mcp.coverbase.app/mcp"
}
}
}
}
```
Reload VS Code and sign in to Coverbase when Copilot prompts you.
## Microsoft Copilot Studio
Copilot Studio can call Coverbase as a Model Context Protocol tool.
In your agent, open **Tools → Add a tool → Model Context Protocol**, then add a new MCP server.
Set the transport to **Streamable HTTP** and enter the server endpoint `https://mcp.coverbase.app/mcp`.
Choose **OAuth 2.0** authentication. Copilot Studio uses dynamic discovery to find the authorization server, so no manual endpoint configuration is required. Complete sign-in to Coverbase to finish.
Copilot Studio probes the RFC 8414 §3.1 path-insertion discovery variant (`/.well-known/oauth-authorization-server/{path}`). The Coverbase server serves authorization-server metadata at that path, so dynamic discovery works out of the box. If discovery fails with "Could not discover authorization server metadata," confirm you entered the full `/mcp` endpoint.
## Microsoft ecosystem and other agents
Coverbase works with any framework that speaks MCP over OAuth 2.0 with Streamable HTTP transport, including **Semantic Kernel**, the **Microsoft Agent Framework** (AutoGen), and **Azure AI Foundry** agents. Register `https://mcp.coverbase.app/mcp` as a remote MCP server / tool in your framework's MCP client and let it run the OAuth flow.
Other popular clients:
* **Cline (VS Code):** open the Cline **MCP Servers** panel and add a new remote server with the Coverbase endpoint.
* **Goose:** run `goose configure`, choose to add a remote MCP server, and enter the endpoint.
* **MCP Inspector:** run `npx @modelcontextprotocol/inspector`, enter the endpoint, authenticate, and exercise tools directly.
## Clients without remote MCP support (mcp-remote)
For clients that only support local **stdio** servers, bridge to the remote server with [`mcp-remote`](https://www.npmjs.com/package/mcp-remote):
```json theme={null}
{
"mcpServers": {
"coverbase": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.coverbase.app/mcp"]
}
}
}
```
`mcp-remote` proxies the connection and handles the OAuth handshake in your browser on first use.
## Other clients
Any client that supports MCP with OAuth 2.0 and Streamable HTTP transport should work. The OAuth discovery documents are published at `https://mcp.coverbase.app/.well-known/oauth-protected-resource` and `https://mcp.coverbase.app/.well-known/oauth-authorization-server`. Point your client at the server URL and the rest is standard.
No tools appearing, permission denied errors, write actions not executing, `403 Forbidden` during authentication, and other common issues.
# Anthropic Connectors Directory
Source: https://docs.coverbase.com/mcp/connector-directory
Coverbase in Claude's official Connectors Directory: one-click install, branded card, and a published security review.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase is published in Anthropic's [Connectors Directory](https://claude.com/docs/connectors), the curated list of MCP servers that Claude users can add to their workspace in a single click. Listed connectors ship with a branded card (logo, tagline, screenshots) and a security review from Anthropic's team.
## What this means for you
Add Coverbase from **Settings → Connectors → Browse directory** in Claude.ai. No URL to copy, no permission prompts to dismiss.
The Coverbase logo, tagline, and supported tools render natively in the connectors picker, the same visual treatment as built-in connectors.
Anthropic reviews every directory submission against their [Software Directory Policy](https://support.claude.com/en/articles/13145358-anthropic-software-directory-policy) for safety, security, and tool design before listing.
The directory entry points at the same `mcp.coverbase.app/mcp` endpoint as a custom connector. Data access is still scoped to your Coverbase user and your org's permissions.
## How to add Coverbase from the directory
Click **Settings → Connectors** in the sidebar, then **Browse directory**.
Search for *Coverbase* or filter by the **GRC / Risk** category.
Click **Add**, then **Authorize** to complete the OAuth sign-in in your browser. You'll be sent to Coverbase to confirm the connection.
The Coverbase tools appear in your Claude session immediately. Try one of the [example prompts](/mcp/example-prompts).
Already added Coverbase as a custom connector? You can keep it: the directory entry and a custom entry both point at the same server. Custom connectors render with a generic globe icon, so most users prefer to remove the custom entry and re-add from the directory once they have access.
## What's included in the directory listing
* **Server endpoint**: `https://mcp.coverbase.app/mcp`
* **Transport**: Streamable HTTP (stateless)
* **Auth**: OAuth 2.0 + PKCE
* **Tools**: All 12 dispatcher tools (vendor / assessment / finding / engagement / control / questionnaire / RFP / radar / platform queries, the `get_report` aggregations, the `mutate` write dispatcher, and `mcp_capabilities` discovery)
* **Resources**: Direct URI reads for vendors, assessments, engagements, controls, and findings
* **Prompts**: TPRM workflow templates (vendor onboarding, portfolio risk briefing, and more)
## Custom connector vs directory entry
| | Custom connector | Directory entry |
| - | - | - |
| Install | Paste URL `https://mcp.coverbase.app/mcp` | One click from Browse directory |
| Logo in Claude.ai | Generic globe | Coverbase branded card |
| OAuth | Same Coverbase OAuth flow | Same Coverbase OAuth flow |
| Tool surface | Identical | Identical |
| Security review | Self-managed | Reviewed by Anthropic |
| Updates | Manual reconnect for major changes | Anthropic notifies on breaking changes |
Both routes connect to the same production server and inherit the same Coverbase permissions. The directory entry is purely an installation and discovery improvement.
## Other clients
The directory listing is a Claude.ai surface. To use Coverbase from Claude Code, Claude Desktop, Cursor, VS Code, Microsoft Copilot Studio, or any other MCP client, follow the [Connecting clients](/mcp/connecting) guide. The server endpoint, OAuth flow, and tool surface are identical regardless of where you connect from.
# Example prompts
Source: https://docs.coverbase.com/mcp/example-prompts
Realistic prompts that exercise the core MCP server workflows.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Use these as inspiration, not a script. The patterns below cover the workflows most customers run on a daily and weekly basis.
## Vendor intake
The full intake request runs in conversation. You don't need to say "intake" for any of these; the assistant recognizes the intent. See [Vendor intake in chat](/mcp/vendor-intake) for the whole flow.
> I want to start using Northwind Analytics for product analytics.
The assistant opens an intake session, reads your portal configuration to see which steps your org enabled, researches Northwind and confirms with you that it has the right company, offers a menu of concrete use cases and in-scope services, surfaces any existing vendor of yours that already covers analytics, runs the screening your portal configures, then walks the inherent risk questionnaire with you one question at a time. Every write asks first.
> My team needs a load testing tool and we're looking at Loadspin. Can we buy it?
Same flow. "Can we buy this" and "my team needs" are intake requests, not questions about policy. The assistant starts the request rather than answering in the abstract.
> Is Acme approved for us to use?
The assistant resolves the name to a vendor, checks its onboarding status, and reports it. If there's no approved record, it offers to start the intake rather than stopping at "no".
> We're about to sign with Mixpanel. Do we already have something that does this?
Vendor matching ranks your existing vendors against the request and surfaces prior relationships, so a duplicate purchase gets caught before the request is filed rather than during review. Web alternatives appear too, if your portal enables them.
> That's the wrong Acme. I mean the payments one, acme.io, not the logistics company.
The assistant takes the correction and re-runs matching or picks another candidate. An unconfirmed match is never carried forward into the request.
> Where did my Datadog request get to? Let's finish it.
The assistant finds the open session, reports which questions are still unanswered or still carrying unconfirmed AI drafts, and resumes the walkthrough there.
> What steps does our intake process include?
The assistant reads your portal configuration and reports which steps are enabled and which your org turned off. Useful when you're not sure whether pre-qualification or web alternatives are part of your flow.
> Add Figma as a vendor record only. Skip the intake questionnaire, we already did the review offline.
The only path to a bare vendor record. The assistant states plainly that the vendor will carry no due diligence, waits for you to confirm that, and only then creates it. Requests that don't explicitly ask to skip intake go through the full flow instead.
### Reviewing what comes in
> Walk me through everything waiting in the intake queue.
The assistant lists pending-review sessions and takes them one at a time: the requester's use case and services, the enrichment and duplicate readout, the pre-qualification verdict per criterion, and the questionnaire answers with their inherent risk score.
> Review the intake request for Marqeta and tell me whether anything looks off.
The assistant pulls the full submission, flags weak or inconsistent answers, and proposes approve, reject, or request-follow-up. The decision is a write, so it waits for your confirmation.
> Their data-types answer is too vague. Send it back and ask what customer PII flows to them.
The assistant proposes the follow-up request with your question attached, confirms, and returns the session to the requester.
Submitting an intake request is not approval. At the end of the requester flow a vendor record may exist, but it sits in **Created** status and nobody should start using the vendor until a reviewer decides the request.
## Portfolio and subprocessor analysis
> Which of our vendors use AWS as a subprocessor, and what is the current risk tier for each?
The assistant calls `query_radar(kind="soc2_nth_party")` with relevant aliases in `llm_query_terms` (AWS, Amazon Web Services, S3, EC2), gets back the list of dependent vendors, then calls `query_vendors(kind="risk_summary")` for each to surface tier and open findings count.
> A major Northwind outage is happening. Show me every vendor in our portfolio that depends on Northwind, sorted by criticality.
Same pattern, scoped to Northwind. The assistant can also pull recent radar alerts for the affected vendors to see if any have already filed incident notifications.
> Build me a one-page report of our top 10 highest-risk vendors with their key open findings.
The assistant calls `get_report(report_name="portfolio_risk", top_n=10)`, then drills into each vendor with `query_vendors(kind="detail")` to extract the relevant findings.
## Vendor profiles and assessments
> Give me a full risk summary for Acme Corp, including any open findings and recent radar alerts.
The assistant calls `query_vendors(kind="search")` to resolve the name to an ID, then `query_vendors(kind="detail")` to pull the consolidated profile in a single call.
> Summarize assessment cbqsrw\_abc123 and list the controls that need human review.
The assistant calls `query_assessments(kind="detail")` and surfaces the control evaluations that are flagged or have open findings, so the reviewer can focus on what matters.
> Give me the complete AI summary for the HubSpot assessment. I want the decision summary, the key business risks, the required conditions, and the vendor remediation message.
`query_assessments(kind="detail")` carries only the opening of the summary and says so. The assistant calls `query_assessments(kind="summary")` for the whole report, and pages through it if it runs long.
> List every completed assessment this quarter with its outcome and residual risk level, as a table.
Both fields are on each `query_assessments(kind="search")` row, so this is one call per page rather than one call per assessment. See [Replacing the assessment export](/mcp/assessment-exports) if you are feeding a dashboard.
> Which assessments did we conditionally approve last quarter, and what conditions did we attach to each?
The outcome is on the search rows, so the assistant filters there first, then reads the summary report for only the matching assessments to pull the conditions out of the narrative.
> What does the assessment backlog look like? How many are in progress, and who owns each?
The assistant pulls `get_report(report_name="review_queue")` for the count of open / in-progress assessments and their owners, or `get_report(report_name="assessment_metrics")` for the rolling-window throughput view. (Assessment statuses are workflow stages such as `collecting_documents`, `analyzing_questionnaire`, and `review_evals`; there is no single `in_progress` status, so the review-queue report is the right tool for backlog.)
## Evidence out of documents
Coverbase reads the documents and returns the passage the answer rests on. Full guide: [Asking your documents a question](/user-guides/document-evidence-pull).
> Does Acme encrypt customer data at rest? Check their SOC 2.
The assistant resolves Acme, calls `query_vendors(kind="document_evidence")` scoped to that vendor, and gets a run id back rather than an answer. A model picks the one or two documents most likely to hold it, reads them, and locates the passage. A minute or two later the assistant calls `query_vendors(kind="document_evidence_result", run_id=...)` and reports the answer with its verbatim quote, the page, a cropped image of the highlighted passage, and a link that opens the document there.
> What is the termination notice period in Acme's MSA, and quote the clause.
Naming the document type narrows the candidate set before anything is read. The quote comes back verbatim, so it can go straight into a negotiation note.
> In the Acme penetration test report, were any critical findings left unresolved?
Naming a document skips the selection step and reads that document.
> I need evidence that Northwind does background checks on staff with production access. Find it and give me something I can cite.
The answer arrives with a page citation and a permanent Coverbase link. Paste the link into the assessment rather than the image: the image link expires after about an hour.
> Does Acme have a documented incident response SLA?
If the documents read do not address it, the response says so rather than inferring an answer. Ask the assistant to widen the scope (drop the document type, raise the document limit) before concluding the control does not exist.
## Vendor intelligence
> Is Acme Corp a real registered company? Show me the legal entity and where you got it from.
The assistant calls `query_vendors(kind="company_registration")`, which returns the validated corporate identity from GLEIF, OpenCorporates, and SEC EDGAR (official registered name, status, jurisdiction, and identifiers) with a link to each register's record. If nothing matched confidently, it says so rather than offering the nearest guess.
> What's the security posture for Acme Corp, and what should I raise with them?
The assistant reads the vendor's outside-in security posture: the rating and grade, the per-factor breakdown with the observed values behind it, the ranked next steps (most urgent first, each naming the evidence it rests on), and what changed since the previous scan. Ask it to draft the questions and it quotes the observed values, such as `p=none` or the CVE identifier, rather than paraphrasing them.
> What's the financial health score for Acme Corp, and has it moved in the last year?
The assistant calls `query_vendors(kind="financial_health")` and reports the score, risk band, **confidence tier**, pillar breakdown, and 3- and 12-month movement, along with the sources behind each figure and any that were unavailable.
> Which of my tier-1 vendors are in the High or Very High financial risk bands?
The assistant resolves the vendor set, then pulls `query_vendors(kind="financial_health")` per vendor. Ask it to group by confidence tier: a Tier C score is inferred from signals and a Tier A score is computed from filed statements, so the two are not directly comparable and a ranking that mixes them is misleading.
> Is the entity on the Acme contract the same one that's registered and in good standing?
The assistant pulls `query_vendors(kind="company_registration")` for the registered legal name and status and compares it against the counterparty on the contract. A mismatch between the contracting entity and the registered entity is a real finding, not a formatting difference.
## Program health and continuous monitoring
> What is happening across our TPRM program this week? Show me recent assessments, open findings, and radar alerts.
The assistant calls `get_report(report_name="org_activity", days=7)` with reasonable limits. This is the single most useful prompt for a daily standup or weekly review.
> Show me every vendor with overdue findings and their owners so I can chase them.
The assistant calls `query_findings(kind="list_detailed")` org-wide with a status filter for open and a date filter for past-due, then groups by assignee.
> Are there any new radar alerts on our tier-1 vendors in the past 24 hours?
The assistant calls `query_radar(kind="alerts")` filtered by vendor ID for the tier-1 list, or asks `get_report(report_name="org_activity", days=1)`.
## Contracts and obligations
> What contracts expire in the next 90 days, and which of those vendors have unresolved findings?
The assistant calls `query_engagements_contracts(kind="contracts")` with the date filter, then for each result calls `query_findings(kind="search")` scoped to that vendor.
> Are there any obligations coming due next month that have not been assigned to anyone?
The assistant calls `query_engagements_contracts(kind="obligations")` filtered by due date and missing assignee.
## Sourcing and RFPs
> Draft an RFP to replace our applicant tracking system for about 12 recruiters. It has to integrate with our HRIS and Microsoft 365, and we will not grant tenant-wide mailbox access.
The assistant calls `mutate(entity="rfp", action="draft_brief")`, which writes nothing and returns a proposed name, description, narrative and timeline for you to correct.
> Who should we invite? Show me what each is known for and what to watch out for.
`mutate(entity="rfp", action="research_vendors")` returns five to ten candidates with the reasoning behind each. Still no write.
> Suggest requirements and questions for it, then create the RFP with those and the four vendors I picked.
`suggest_requirements` and `generate_questions` propose the rubric and questionnaire; `create`, with `confirm: true`, builds the RFP, rubric, questionnaire, vendor records and invitations in one transaction, as a draft.
> Run it silently and tell me how they stack up.
`simulate_submissions` researches how each invited vendor would most plausibly answer, then `compare` reads the whole set together. Every rendering states that these are researched estimates, not vendor responses. A vendor who already sent a real response is skipped.
> What did Greenhouse say about mailbox scopes?
`query_rfps(kind="submission_answers")` returns that submission's answers, each labelled with whether it came from the vendor or from research.
## Bill of materials
> Show me the latest software bill of materials for vendor Acme and list its components.
The assistant calls `query_vendors(kind="search")` to resolve the name, then `query_vendors(kind="bill_of_materials", vendor_id=...)` to pull the current applied BOM and its components in one call.
> Does Acme's current SBOM include any GPL-licensed components?
Same `bill_of_materials` call, then the assistant filters the returned components by their `licenses`.
> What AI models and datasets are in Acme's AIBOM?
The assistant pulls the latest BOM and surfaces the `machine-learning-model` and `data` components.
> Pull the components from Acme's latest hardware BOM.
The assistant calls `query_vendors(kind="bill_of_materials", vendor_id=...)` and lists the hardware components.
> List every bill of materials we've received from Acme over time. Which one is currently applied?
The assistant calls `query_vendors(kind="bill_of_materials_history", vendor_id=...)`. The list comes back newest first; the first entry is the applied one.
> Has Acme ever shipped a BOM that contained `openssl`? Show the history.
The assistant calls `query_vendors(kind="bill_of_materials_history", vendor_id=...)` and checks each BOM's components for the match, tracing every hit back to its source document.
**What these call:** `query_vendors(kind="bill_of_materials", vendor_id=...)` or `query_vendors(kind="bill_of_materials_history", vendor_id=...)`, both read-only and user/org-scoped. See the [Bill of Materials API](/api-reference/bill-of-materials#mcp-assistant-access) for the full argument list.
## Write actions, with confirmation
Every write tool requires the assistant to propose the action in chat and wait for your explicit approval. The examples below show the pattern.
> Add a note to vendor Acme Corp: following up with their security team next week.
The assistant proposes: *"I am about to add a note to Acme Corp with the text 'following up with their security team next week.' Confirm?"* After your approval, it calls `mutate(entity="note", action="add", data={..., "confirm": true})`.
> Create a finding on assessment cbqsrw\_abc123 titled "Missing encryption at rest evidence" and assign it to me.
The assistant proposes the finding (title, body, assessment ID, assignee), waits for confirmation, then calls `mutate(entity="finding", action="create", data={..., "confirm": true})`.
> Update the risk tier of vendor Globex to Tier 1.
The assistant proposes the change to the vendor status, confirms, then calls `mutate(entity="vendor", action="update", data={..., "confirm": true})` with the relevant status ID.
> Log a radar event for Acme Corp: they disclosed a data breach today.
The assistant proposes the event (name, summary, impact type, vendor), waits for confirmation, then calls `mutate(entity="radar_event", action="create", data={..., "confirm": true})`.
> That radar alert about Acme is a duplicate. Dismiss it and suppress similar ones.
The assistant proposes the dismissal (alert ID, reason, `suppress_similar`), confirms, then calls `mutate(entity="radar_alert", action="dismiss", data={..., "confirm": true})`.
> Kick off a reassessment of Acme Corp because of that breach event.
The assistant lists reassessments via `query_radar(kind="reassessments")` to check for an existing one, then proposes a new reassessment (radar event, vendors, optional plan) and calls `mutate(entity="reassessment", action="create", data={..., "confirm": true})`. This never opens a case.
## Tuning the AI
> Which of our controls raise issues most often? I think some are misfiring.
The assistant calls `get_report(report_name="control_flag_rates")` to rank controls by issue-flag rate across recent assessments, with a volume floor so a control evaluated twice doesn't top the list. Pass `format='csv'` if you want it in a spreadsheet.
> Go through the flagged issues on assessment cbqsrw\_abc123 with me and clear the ones that aren't real.
The assistant walks each flagged evaluation with its evidence, and for the ones you clear calls `mutate(entity="eval", action="update", data={..., "outcome": "not_an_issue", "confirm": true})`.
> That control keeps flagging vendors who do have MFA. Rewrite its guidance.
The assistant proposes new expectation, evaluation instruction, or evidence requirement text, confirms, then calls `mutate(entity="control", action="update", data={..., "confirm": true})`. Material edits create a new version rather than overwriting the old one. Re-run the analysis with `mutate(entity="assessment", action="rerun", ...)` to re-evaluate against the new guidance.
## Related
Twenty scripted workflows you can invoke by name, including `weekly_briefing`, `submit_intake_request`, and `tune_control_guidance`.
Every route these prompts resolve to, and the parameters each accepts.
Every Consolidated Assessment Report column mapped to the call that returns it, with sample input and output.
# Coverbase MCP Server
Source: https://docs.coverbase.com/mcp/overview
Let AI assistants query and manage your TPRM program through natural conversation.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Coverbase MCP server lets AI assistants and agentic tools query and manage your third-party risk and procurement program through natural conversation. Ask about vendors, assessments, findings, contracts, obligations, and subprocessor exposure, and the assistant pulls answers directly from your Coverbase account, scoped to your permissions.
The server implements the [Model Context Protocol](https://modelcontextprotocol.io), an open standard for connecting AI assistants to external systems. It works with any MCP-compatible client.
## Supported clients
claude.ai web, Claude Desktop, Claude for Chrome
Anthropic's command-line agentic coding tool
The AI-native IDE
GitHub Copilot agent mode (native MCP)
MCP tools for Copilot agents
The VS Code coding agent
Block's open-source AI agent
The official Anthropic debugging client
If your tool speaks MCP over OAuth 2.0 with Streamable HTTP transport, it will work with our server. Email [support@coverbase.ai](mailto:support@coverbase.ai) if you'd like us to add yours to the test matrix.
## What you can do
The server exposes 12 tools, each dispatching many operations, across read and write capabilities.
File a complete vendor intake request in conversation: the assistant researches the vendor and confirms its identity with you, surfaces existing vendors that already cover the need, runs the pre-qualification and duplicate checks your portal configures, then walks the inherent risk questionnaire one question at a time. Reviewers can work the pending queue the same way, approving, rejecting, or requesting follow-up. See [Vendor intake in chat](/mcp/vendor-intake).
Search vendors by name, status, tier, owner, or tags. Pull a full vendor profile in one call: people, assessments, findings, contracts, engagements, obligations, radar alerts, security cases, and SOC 2 documents. Read a vendor's latest applied bill of materials (SBOM, AIBOM, HBOM, SaaSBOM) and its components, or its full BOM upload history. Surface portfolio-wide views including highest-risk vendors, evidence health, assessment metrics, Zero Touch Score rankings, and your risk register, and run what-if risk scenarios.
Search assessments by vendor, status, or assignee. Get full assessment detail in one call: control evaluations, findings with titles, people, supporting documents. List control sets, controls within a set, and per-control evaluation results. Start new assessments, update fields, and manage assessment plans.
Search findings scoped to a vendor or assessment, or org-wide, with full titles, categories, assignees, due dates, and status. List follow-ups attached to assessments. Search and update obligations extracted from vendor documents. Create new findings or obligations with explicit confirmation.
Search contracts by vendor or status, and get full contract detail. List vendor engagements and vendor documents (evidence files) for a vendor or org-wide. Get evidence health summaries.
List RFPs and read one in full: timeline, rubric, invited vendors, submissions and their answers, and the stored cross-vendor comparison. Draft a brief, research candidate vendors, create and publish the RFP, compare submissions, and award it, each write with confirmation. See [How to run an RFP](/user-guides/running-an-rfp).
Search across all vendors' SOC 2 reports and custom relationships to find which vendors depend on a specific nth-party. The question that takes hours in most TPRM tools and seconds here: "which of our vendors use AWS as a subprocessor?"
Rank controls by how often they flag an issue across recent assessments to find the false-positive-prone ones, then tune a control's expectation, evaluation instructions, or evidence requirement so it stops misfiring. Material edits create a new version rather than overwriting. Clear individual false positives on a single assessment, and re-run the analysis against the new guidance.
List radar alert events for a single vendor or across the org. List and update radar detectors configured for the org. Seed a radar event manually, dismiss a noisy alert (optionally suppressing similar ones), and start a reassessment from an event with its impacted vendors.
Get an org activity digest in one call: recent assessments, open findings, radar alerts, audit trail entries, and notifications. List the audit trail for any supported object.
List and add notes on any platform object. List and update tags, custom field configurations, custom field values, workflow automations, assessment plans, questionnaires, status labels, and org users.
Every route on all 12 tools: the read `kind` values, the report catalog and their parameters, and the complete write matrix.
Every tool that creates, updates, or deletes data requires a `confirm` parameter set to `true`. The assistant is expected to surface the proposed change in chat and wait for your approval before executing. This human-in-the-loop pattern applies uniformly across all write tools.
## Server endpoint
```text theme={null}
https://mcp.coverbase.app/mcp
```
## Connecting
`claude mcp add --transport http coverbase https://mcp.coverbase.app/mcp`
Add a custom connector in Settings → Connectors
Add a custom connector in Settings → Connectors
Add as a remote MCP server in Cursor settings
Native MCP in GitHub Copilot agent mode
Add as a Model Context Protocol tool
Any MCP client with OAuth 2.0 and Streamable HTTP transport
## Requirements
* An active Coverbase account on a plan that includes API access.
* An MCP-compatible AI assistant or client.
* The MCP server uses OAuth 2.0. Your permissions in Coverbase determine what the connected assistant can see and do.
Run a full intake request in conversation: identity confirmation, alternatives, screening, and the questionnaire.
Every route on all 12 tools, with the parameters each accepts.
Twenty scripted workflows you can invoke by name instead of describing.
Realistic phrasing for the workflows customers run daily and weekly.
How read-only versus read/write is decided, and how it maps to your Coverbase role.
How we handle credentials, what we log, what we don't retain, and how to revoke access.
# Roles and permissions
Source: https://docs.coverbase.com/mcp/permissions
How the MCP server enforces read-only versus read/write access, why it inherits the connected user's Coverbase role, and the controls that keep every tool call least-privilege.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Coverbase MCP server does not have its own permission system. Every tool call runs as the person who authorized the connection, with exactly the access that user already has in Coverbase, no more. There are no separate MCP credentials, no service identity that sees more than the user, and no way for the assistant to escalate beyond what the user could do in the dashboard.
This page explains how that works end to end: how a request is authenticated, how a role is resolved, and how read-only versus read/write access is decided and enforced.
**The short version.** Two things decide access: the **role** of the identity connecting, and the **scopes** on the credential. **Admins** and **Members** can write; **Guests** and **Siloed Members** are read-only. On top of that, an API key can be minted **read-only**, which withholds write regardless of role. Change someone's role in Coverbase and it takes effect on their next request; there is nothing separate to re-issue.
## Permission inheritance
When a client connects, the user signs in to Coverbase through OAuth 2.0 and authorizes the connection. From that point on, every tool the assistant calls is evaluated against **that user's live organization membership**. The connector is a delegate, not a privileged service account.
Three properties follow from this design:
The assistant can never see or do more than the connected user could do by logging into the dashboard themselves.
Permissions are read from the user's organization membership, not from a static config baked into the connector or copied at install time.
Every call is scoped to the user's organization. The client never supplies an organization ID; the server derives it from the authenticated session.
## Role-to-access matrix
Coverbase organization roles map to MCP access as follows.
| Role | Can connect to MCP? | Read tools | Write tools |
| - | - | - | - |
| **Admin** | Yes | Yes | Yes |
| **Member** | Yes | Yes | Yes |
| **Siloed Member** | Yes | Yes | No (read-only) |
| **Guest** | Yes | Yes | No (read-only) |
| **Auxiliary Member** | No | - | - |
| **Custom role** | No | - | - |
| **Service Account** | API key only | Yes | No (read-only) |
A few specifics:
* **Read access** (search vendors, pull assessment detail, list findings, run portfolio reports, and so on) is available to every role that can connect.
* **Write access** (creating or updating vendors, assessments, findings, obligations, notes, tags, and other records) is reserved for **Members** and **Admins**.
* **Auxiliary Members** cannot use the MCP server at all, and receive a `403` if a token for one is ever presented.
* **Custom roles** cannot connect. The write guard cannot express a custom role's permissions, so rather than silently forcing a possibly write-capable user to read-only, the server refuses the connection. Give the user one of the default roles above.
* **Service Accounts** are non-interactive by design, so they cannot sign in through OAuth or a dashboard session; those paths still return `403`. They *can* hold an API key, which is what makes a programmatic read-only connection possible without a human seat. A service account can never write through MCP.
The MCP write boundary is deliberately conservative. Write access through the connector is limited to Members and Admins, so it is **never broader** than what the same user could do in the dashboard. For some roles it is intentionally tighter. If you need a user to make changes through an assistant, give them the Member or Admin role.
## How a request is authorized
Every request flows through the same gate, regardless of which client or token type it uses. There is no path that skips role resolution.
The server accepts three token formats on the `Authorization: Bearer` header: an OAuth 2.0 access token issued to a remote MCP client, a dashboard SSO session token, or a long-lived Coverbase-issued MCP API key. Anything else is rejected with `401`.
The user's organization role is resolved from their **current** membership record, not from anything cached in the client. For API-key and session tokens, the membership is looked up on every request. For OAuth tokens, the role is bound to the token from live membership at authorization time and **re-validated every time the token is refreshed** (see [Live revalidation](#live-revalidation)).
If the resolved role is not one of the connectable roles (Guest, Siloed Member, Member, Admin, plus Service Account on an API key), the request is rejected with `403` before any tool runs. Auxiliary Members and custom roles are not connectable.
Read tools proceed for any connectable role. Write tools pass through an additional guard described in [Write protection](#write-protection) before they touch any data.
The organization is taken from the authenticated session and applied to every query automatically. The client cannot widen the scope by passing a different organization ID; there is no parameter to do so.
## Write protection
Read-only versus read/write is not a single switch: a write tool only executes when **three independent conditions** are all satisfied. Any one of them failing returns a clear, non-destructive error instead of performing the change.
The connected user's role must be **Member** or **Admin**. Guests and Siloed Members receive a message explaining that their role cannot run write tools, and are pointed to ask a Member or Admin.
The credential must carry the **`mcp:write`** scope. An API key minted read-only, or an OAuth token issued without it, produces a strictly read-only connection even for a user whose role would otherwise allow writes. (See [Scopes](#scopes).)
Every write tool requires an explicit `confirm=true` argument. Without it, the tool returns a precondition error rather than executing, so the assistant is forced to surface the proposed change to you and wait for your approval before anything is written.
These checks are applied **server-side**, inside the write guard, before any database write. They do not rely on the client or the model behaving correctly. A misbehaving or compromised client cannot bypass the role check, the scope check, or the confirmation requirement.
## Scopes
The server defines two scopes:
| Scope | Grants |
| - | - |
| `mcp:read` | Access to all read tools (search, detail, reports). |
| `mcp:write` | Access to write tools, in combination with a write-capable role and explicit confirmation. |
Every credential carries `mcp:read`. Whether it also carries `mcp:write` is fixed when the credential is issued:
* **API keys** store their scopes on the key itself. Tick **Read-only** when you generate one under **Configuration → MCP Server** and the key never carries `mcp:write`, not now and not if the owner is promoted to Admin later. The key list shows the grant on each key.
* **OAuth tokens** are issued with both scopes by default. The authorization endpoint also accepts a narrower `scope` request, so a client can ask for `mcp:read` alone.
A read-only credential is not merely refused at the last moment. The `mutate` tool is **hidden** from such a connection: it does not appear in the client's tool list, and `mcp_capabilities` reports no mutations. The assistant never proposes a change it cannot make, so you are never asked to confirm a write that was going to fail.
## Programmatic read-only access
The common case is a pipeline, a scheduled report, or an internal assistant that should read Coverbase and never change it. You do not need a human seat for this.
Go to **Configuration → MCP Server** and choose **New API key**.
**Service account** is the usual answer: a built-in non-human identity that needs no seat in your identity provider and never signs in. Choose **Another user** instead to attribute the key's activity to a particular member, such as a Guest kept for reporting.
Either choice makes the key **read-only automatically**. A key that authenticates as someone else can never write, so a change is never recorded under a name that did not make it.
The secret is shown once. Send it as `Authorization: Bearer cb_mcp_...` from your client. See [Connecting clients](/mcp/connecting).
You keep control of a key you minted for a service identity: it appears in your key list and you can revoke it, even though it authenticates as something else. For what shows up in the audit trail once it is running, see [Attributing a key that acts as a service account](#attributing-a-key-that-acts-as-a-service-account).
**Want a guaranteed read-only connection?** Any one of these is sufficient on its own, because the write guard requires *both* a write-capable role *and* the write scope:
1. Mint the API key **read-only**.
2. Bind the key to a **service account** or another user, which forces read-only.
3. Connect with a **Guest** or **Siloed Member** account; their role blocks writes regardless of scope.
## Live revalidation
Because permissions are resolved from live membership, changes you make in Coverbase propagate without any re-install or token re-issuance on the user's side.
* **API-key and session tokens** look up the user's membership on **every request**. If the user has been removed from the organization, the request is rejected with `403`, even if the token itself is still otherwise valid. A key's *scopes* do not follow the role: a read-only key stays read-only through any promotion, which is what makes it safe to hand to an automation.
* **OAuth tokens** bind the role at authorization time and **re-check live membership on every refresh**. A user who is demoted (for example, Member → Guest) or removed from the organization cannot keep using a previously elevated token past its expiry: the next refresh either downgrades the role baked into the new token or fails outright. Access tokens last up to 24 hours and clients refresh silently, so a role change on an OAuth connection takes effect within a day at most.
This means a demotion is also a downgrade of MCP access, and a removal is a revocation, without anyone needing to touch the connector. For API keys it is immediate; for OAuth connections it lands at the next token refresh. Revoking an MCP API key under **Configuration → MCP Server** stops it at once. Disconnecting a client removes the tokens that client holds, but Coverbase has no separate switch to invalidate an OAuth access token that was already issued.
## What this means in practice
The assistant can search vendors, pull the vendor's full profile, list findings and assessments, and run reports; all read operations succeed. The update is **blocked by the role check** and the assistant is told the user's role cannot perform writes. No data is changed.
The role check passes (Member is write-capable) and the default token carries `mcp:write`. The assistant proposes the new finding and waits. Once you confirm, it re-runs the tool with `confirm=true` and the finding is created, and the action is recorded in the audit trail.
On the user's next request (API key/session) or next token refresh (OAuth, within 24 hours), the new Guest role takes effect. Subsequent write attempts are rejected. There is nothing to reconfigure on the user's machine.
An API key or session token fails with a `403` on the next request, because there is no active membership to resolve a role from. An OAuth connection keeps working until its current access token expires (up to 24 hours), and the refresh then fails.
## Auditability
Every tool call, read or write, is logged with the connected identity, the tool name, the parameters, a timestamp, and the outcome. Write actions taken through the MCP server land in the same Coverbase audit trail as actions taken in the dashboard, so administrators have one consolidated record of who did what, regardless of whether it happened through the UI or an assistant.
### Attributing a key that acts as a service account
A reasonable question about any non-human credential: if it changes something, whose name is on it?
For MCP keys the answer is that it cannot change anything. A key bound to a service account or to another user is read-only, and a service account is additionally excluded from the write-capable roles. **A bound key never produces a write in your audit trail**, so there is no such thing as a change you cannot trace to a person. Only a key that acts as *you* can write, and those entries carry your name exactly as if you had made the change in the dashboard.
What you can still see for a bound key:
Creating and revoking an MCP key are recorded in **Configuration → Audit Logs** under **Integrations**, attributed to the admin who did it, with the key's name. The key also stores that admin internally, so a key always traces back to a person even though it runs unattended.
Every tool call the key makes is logged with the connected identity, the tool, the arguments, and the outcome. Read activity is recorded, not only writes.
**One service account identity is shared by every integration in your organization**, and it is the same identity behind your REST API keys. Two MCP keys bound to it are not distinguishable from each other in the per-call logs, which record the identity rather than the individual key.
So issue **one key per integration** rather than reusing a single key across several, and give each a name that says what it is for. That way the provisioning record in the audit log tells you which integration was set up when and by whom, and revoking one key stops exactly one integration instead of all of them at once.
This differs from the [REST API](/conventions#public-api-audit-log), where each request records the calling `ak_` key's id and name alongside the shared identity. Per-key attribution on individual MCP tool calls is not available today.
If you need machine activity attributed to a distinct named identity rather than the shared service account, bind the key to a dedicated user instead: create a **Guest** for it and use **Another user** when generating the key. That costs a seat in your identity provider, which the service account option avoids, so it is a trade between attribution granularity and provisioning overhead.
Authentication, transport security, what we log, what we don't retain, and how to revoke access.
# Canned prompts
Source: https://docs.coverbase.com/mcp/prompts
Twenty scripted TPRM workflows you can invoke by name instead of describing what you want.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Alongside its tools, the server publishes **prompts**: scripted multi-turn workflows you invoke by name. Each one hands the assistant a sequence to follow, so you get the same shape of output every time instead of whatever the model improvises.
How you invoke one depends on your client. In Claude, prompts appear in the attachment or slash menu once the connector is added. In other clients, look for "prompts" or "templates" in the MCP integration.
Prompts are a convenience, not a gate. Everything below is reachable by describing what you want. The value is repeatability: the same review runs the same way each week, and the steps that are easy to skip don't get skipped.
Prompts that lead to a write always instruct the assistant to get your explicit confirmation first. A prompt never grants standing permission to mutate data.
## Vendor intake
**Argument:** `vendor_name`
Files a new vendor intake request end to end: opens the session, reads your portal configuration, researches and confirms the vendor's identity, surfaces existing vendors that already cover the need, runs your configured screening, and walks the inherent risk questionnaire one question at a time.
See [Vendor intake in chat](/mcp/vendor-intake) for the full flow.
**No arguments.**
Walks every pending-review intake session in turn: the requester's use case and services, the enrichment and duplicate readout, the screening verdict, and the questionnaire answers.
**Argument:** `intake_session_id`
Approve, reject, or request follow-up on one intake session.
**Arguments:** `vendor_name`, `use_case` (optional)
Adds a bare vendor record with **no due diligence**. Only for when you explicitly want to skip intake. The assistant states what you're giving up before it creates anything.
## Assessments and controls
**Argument:** `assessment_id`
Walks approving or sending back one assessment.
**Argument:** `assessment_id`
Walks one assessment's flagged issues, clears the false positives, and suggests guidance fixes so the same control stops misfiring next time.
**Argument:** `days` (default 180)
Finds over-flagging controls across recent assessments and tunes their AI guidance to cut false positives. The companion to `false_positive_review`: one fixes the instance, this one fixes the cause.
**Argument:** `assessment_id`
Produces an executive-ready report for a single assessment.
**Argument:** `vendor_name`
Generates a pre-onboarding due diligence checklist for a new vendor.
## Findings, evidence, and obligations
**No arguments.**
Walks overdue and open findings, grouped so you can chase the right owners.
**No arguments.**
Identifies and prioritizes vendors with expiring or missing evidence.
**Argument:** `vendor_id`
An evidence health audit for one vendor.
**Arguments:** `vendor_name`, `question`
Answers a plain-English question out of a vendor's stored documents. Resolves the vendor, looks at what evidence exists, starts a pull, waits for it, then reports each answer with its verbatim quote, page number, confidence, snippet image, and a link that opens the document with the passage highlighted.
Reading documents takes a couple of minutes, so the prompt starts the run and collects the result rather than blocking. See [Asking your documents a question](/user-guides/document-evidence-pull) for the full flow.
**Argument:** `months_ahead` (default 6)
Contracts expiring in the next N months, with the vendor risk context attached.
## Monitoring and investigation
**Argument:** `days` (default 7)
Walks new radar alerts and what to do about each.
**Argument:** `vendor_name`
A detailed read of one vendor's risk posture.
**Arguments:** `object_type`, `object_id`
Investigates the audit trail for a single platform object. The answer to "who changed this, and when".
## Reporting
**Argument:** `days` (default 7)
A weekly TPRM executive briefing. The most-used prompt for a Monday standup.
**No arguments.**
An executive risk briefing across the vendor portfolio.
**Argument:** `days` (default 90)
A board-ready program report over a quarter-length window.
## Related
Free-form phrasing for the same workflows, when you don't want to invoke a prompt by name.
The 12 tools these prompts drive, and every route each one covers.
# Security and privacy
Source: https://docs.coverbase.com/mcp/security
Authentication, authorization, data handling, and what we log when you connect the MCP server.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
## Authentication and authorization
The Coverbase MCP server uses OAuth 2.0. We do not store the AI assistant provider's credentials, and the AI assistant provider does not receive your Coverbase password.
Access tokens expire after 24 hours and are renewed with a refresh token. Each refresh re-checks the user's organization membership and issues a new refresh token.
Tool calls run with the connected user's permissions. The connector cannot escalate beyond what that user could do in the Coverbase UI. See [Roles and permissions](/mcp/permissions) for the full model.
The server validates the `Origin` header on incoming MCP requests to prevent DNS rebinding attacks.
All connections use TLS 1.2 or higher with certificates from recognized authorities.
## What we log
When the connector is invoked, we log:
* The OAuth user identity
* The tool called
* The parameters passed
* The timestamp
* The outcome (success or error)
These logs are used for security monitoring, debugging, abuse prevention, and audit. They are retained in line with the retention periods described in our privacy policy.
## What we do not retain
* We do not retain the prompts you send to the AI assistant.
* We do not retain the conversation context the assistant maintains.
* We do not retain the assistant's responses to you.
* We do not collect data outside the scope of the specific tool calls made by the assistant.
* We do not access the assistant's chat history, memory, or files.
The AI assistant provider (for example, Anthropic for Claude) is a separate controller for the prompts you send to it and the responses it generates. Their handling of your data is governed by their own privacy policy.
## Revocation
You can disconnect the connector at any time from the assistant client's connector settings, which removes the tokens that client holds. Coverbase has no separate switch to invalidate an OAuth access token that was already issued: it stays valid until it expires (up to 24 hours). Removing the user from your organization stops the next refresh, and an MCP API key revoked under **Configuration → MCP Server** stops working immediately.
## Write-action protection
Every tool that creates, updates, or deletes data requires an explicit `confirm` parameter set to `true`. The assistant is expected to surface the proposed change in chat before execution. Calls without confirmation return a precondition error rather than executing silently.
## Audit logging
Every tool call is logged with user identity, sanitized parameters, and outcome in Coverbase's security logs. Changes made through the connector run as the connected user and appear in the Coverbase audit trail attributed to that user, alongside actions taken in the dashboard. See [Audit trails](/security/audit-trails) for the full model: what is captured, where to review it, and how to export it.
## Compliance
The Coverbase MCP server is part of our SOC 2 Type II audited platform and inherits the same controls as the core product.
## Vulnerability reporting
Report any security issue to [security@coverbase.ai](mailto:security@coverbase.ai). We acknowledge reports within one business day and follow responsible-disclosure timelines.
See the MCP section of the Coverbase Privacy Policy for full details.
# Tool reference
Source: https://docs.coverbase.com/mcp/tool-reference
Every tool the Coverbase MCP server exposes: the nine read dispatchers and their kinds, the report catalog, the write matrix, and the self-describing capabilities call.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The server exposes **12 tools**. Nine of them are read dispatchers, one per domain, each covering many operations through a `kind` parameter. One returns reports, one performs every write, and one describes the rest.
This shape is deliberate. An assistant handed sixty-five narrowly-named tools spends its context deciding between them and still picks wrong; a dozen tools with explicit routes leave more room for your actual data.
You rarely need this page to *use* the server. Ask for what you want in plain language and the assistant picks the route. This is here for when you want to know exactly what it can reach, audit what an assistant did, or write a prompt that names a specific call.
## Reads
Each read tool takes a `kind` and the identifiers that kind needs. All are read-only and scoped to your organization and your permissions.
### `query_vendors`
Accepted parameters: `kind`, `vendor_id`, `document_id`, `query`, `llm_query_terms`, `run_id`, `document_type`, `document_status`, `service_id`, `uploaded_after`, `uploaded_before`, `limit`.
| `kind` | Returns |
| - | - |
| `search` | Vendors matching a name or filter. |
| `count` | How many vendors you have. |
| `detail` | The consolidated profile: people, assessments, findings, contracts, engagements, obligations, radar alerts, documents. One call. |
| `people` | Contacts on a vendor. |
| `onboarding_status` | Where a vendor sits in onboarding. Takes an ID, not a name. |
| `documents` | Evidence files for a vendor, or org-wide. Narrows on `query`, `document_type`, `document_status`, `service_id`, `uploaded_after`, `uploaded_before`. |
| `document_summary` | A summary of one document. |
| `document_download` | A download link for one document. |
| `document_evidence` | Starts reading the documents themselves to answer a question. Returns a run id, not the answer: a model picks which one or two documents to read (`limit`, default 2, max 5) and reads them. Takes a couple of minutes. |
| `document_evidence_result` | The answer from a started pull, by `run_id`: per document, an answer, a verbatim quote with its page, a confidence, a snippet image, and a link that opens the document highlighted. Omit `run_id` to list recent pulls. |
| `risk_summary` | Risk tier and open finding counts. |
| `financial_health` | The Coverbase Financial Health Score: 0-100 score, risk band, confidence tier, pillar breakdown, financial vitals, peer percentile, adverse events, and the source behind each figure. Never compare scores across confidence tiers. |
| `company_registration` | Validated corporate identity from GLEIF, OpenCorporates, and SEC EDGAR: official name, status, jurisdiction, addresses, and LEI / DUNS / company number / CIK, each with a citation. Prefer this over a web search when a corporate fact is in question. |
| `leadership` | The vendor's [People Intelligence](/products/people-intelligence) dossier: executives, board and key people, who reports to whom, registry filings that name them, and adverse-media and sanctions screening. Separates confirmed names from unconfirmed research candidates. |
| `security_posture` | The outside-in [security posture](/products/security-intelligence) measured against the vendor's own infrastructure: rating and grade, per-factor findings, actively exploited vulnerabilities, and lookalike domains. Requires Advanced company intelligence for your organization. |
| `bill_of_materials` | The currently applied SBOM, AIBOM, HBOM, or SaaSBOM and its components. |
| `bill_of_materials_history` | Every BOM received from this vendor, newest first. |
| `uses_nth_party` | Which of your vendors depend on a named nth-party. |
### `query_assessments`
Accepted parameters: `kind`, `assessment_id`, `eval_id`, `vendor_id`, `status`, `query`, `control_set_id`, `issues_only`, `unresolved_only`, `limit`, `full_text`, `analysis_offset`, `summary_offset`, `recommendation_offset`.
| `kind` | Returns |
| - | - |
| `search` | Assessments by vendor, status, or assignee. Each row carries the outcome and the residual risk, so a whole portfolio maps in one call per page. |
| `zero_touch` | One [Zero Touch](/products/zero-touch-assessments) run: its composite Zero Touch Score, the components behind it, whether the score was applied, and every source cited. |
| `zero_touch_leaderboard` | Vendors ranked by their latest Zero Touch Score, worst first, one row per vendor. |
| `zero_touch_audit` | Every review action on a Zero Touch run (approvals, escalations, corrections to its inputs) and what each did to the score. |
| `detail` | Full assessment: outcome, residual risk, control evaluations, findings with titles, people, documents, and the scope columns (date created, initiated by, run counter, products, services, control sets, parsed control counts). Carries the opening 500 characters of the AI summary as a preview. |
| `summary` | The complete AI-generated summary report: every section the summary prompt produced, plus the recommendation, the residual risk, and any notices. This is the **Summary** column of the Consolidated Assessment Report export. |
| `details_legacy` | The previous detail shape, for compatibility. Carries the outcome and residual risk too. |
| `evals` | Per-control evaluation results. Filterable to issues only or unresolved only. |
| `eval_detail` | One control evaluation in full, including the AI's complete reasoning. |
| `plans` | Assessment plans. |
| `follow_ups` | Follow-ups attached to an assessment. |
Every export column mapped to the call that returns it, with sample input and output.
Reading a long AI analysis: `eval_detail` renders the AI's reasoning whole up to a generous cap. If an analysis is longer than that, the response says so and names the follow-up call that returns the rest: pass `full_text=true` for every section at maximum length, or `analysis_offset` to page through the analysis from a given character. A capped response always announces itself, so a partial analysis is never presented as the complete reasoning.
Reading a long summary report: `summary` works the same way. Pass `full_text=true`, or `summary_offset` (and `recommendation_offset` for the recommendation section), to page through a report longer than one response can carry. The truncation notice names the exact call that returns the next window.
### Risk scores and your scoring settings
Two settings under **Configuration → Scoring** change what every read returns, matching what the Consolidated Assessment Report export drops:
| Setting off | Effect |
| - | - |
| Residual risk tracking | Residual risk is omitted everywhere, level and score alike. A workspace that turns this off does not compute the value, so the stored numbers are whatever the last computation left behind. |
| Numerical scores | Raw inherent and residual risk **numbers** are omitted and the named levels stay. The assessment score percent is a separate column and is unaffected. Vendors are still ranked by inherent risk in the portfolio report, without the score printed. |
### `query_findings`
Accepted parameters: `kind`, `finding_id`, `vendor_id`, `assessment_id`, `commitment_id`, `commitment_status`, `limit`.
| `kind` | Returns |
| - | - |
| `search` | Findings scoped to a vendor or assessment, or org-wide. |
| `detail` | One finding in full. |
| `list_detailed` | Findings with full titles, categories, assignees, due dates, status. Use this rather than `search` when you need titles. |
| `commitments` | Vendor commitments. |
| `commitment_detail` | One commitment in full. |
### `query_engagements_contracts`
Accepted parameters: `kind`, `vendor_id`, `engagement_id`, `contract_id`, `vendor_document_id`, `status`, `status_id`, `limit`.
| `kind` | Returns |
| - | - |
| `engagements` | Engagements, optionally scoped to a vendor. |
| `engagement_detail` | One engagement in full. |
| `contracts` | Contracts by vendor or status. `status_id` filters by one of your custom contract workflow statuses, from `query_platform(kind="statuses", target_type="contract")`. |
| `contract_detail` | One contract in full. |
| `services` | Services on a vendor. |
| `obligations` | Obligations extracted from vendor documents. |
### `query_controls`
Accepted parameters: `kind`, `control_set_id`, `control_id`, `limit`.
| `kind` | Returns |
| - | - |
| `search` | Controls, optionally within one set. |
| `detail` | One control, including its AI evaluation guidance. |
| `control_sets` | Your control sets. |
### `query_questionnaires`
Accepted parameters: `kind`, `questionnaire_id`, `questionnaire_type`, `vendor_id`, `intake_session_id`, `status`, `unanswered_only`, `pending_only`, `offset`, `limit`.
| `kind` | Returns |
| - | - |
| `list` | Your questionnaires. |
| `responses` | Responses to a questionnaire. |
| `intake_sessions` | Intake requests, filterable by status. |
| `intake_review` | One intake session as a reviewer sees it. |
| `intake_questions` | The questions on an intake, with AI drafts and reasoning. `pending_only` is the review queue: unanswered questions plus unconfirmed drafts. |
| `intake_prequalification` | The per-criterion screening verdict and its reasoning. |
| `intake_vendor_matches` | Ranked existing vendors and web alternatives for an intake. |
| `intake_steps` | Which steps this org's intake portal turns on **and off**. Authoritative. |
How these fit together into a complete intake request, and why `intake_steps` is read before anything else runs.
### `query_rfps`
Accepted parameters: `kind`, `rfp_id`, `submission_id`, `query`, `limit`.
| `kind` | Returns |
| - | - |
| `list` | RFPs in the org, newest first. |
| `detail` | One RFP: timeline, rubric, vendors and submissions. |
| `submission_answers` | One submission's answers, each labelled with where it came from. |
| `comparison` | The stored cross-vendor comparison, with its timestamp. |
| `activity` | The RFP's event history, including which AI steps ran. |
The full lifecycle, and what a researched response is and is not.
### `query_radar`
Accepted parameters: `kind`, `vendor_id`, `query`, `llm_query_terms`, `include_common_related_terms`, `limit`.
| `kind` | Returns |
| - | - |
| `detectors` | Radar detectors configured for the org. |
| `alerts` | Alert events, for one vendor or org-wide. |
| `reassessments` | Reassessments, including any started from a radar event. |
| `soc2_nth_party` | Which vendors depend on a named nth-party, searched across SOC 2 reports and custom relationships. Pass `llm_query_terms` with aliases: `AWS`, `Amazon Web Services`, `S3`, `EC2`. |
### `query_platform`
Accepted parameters: `kind`, `object_type`, `object_id`, `target_type`, `target_id`, `query`, `include_inactive`, `limit`.
| `kind` | Returns |
| - | - |
| `notes` | Notes on any object. |
| `audit_trail` | The change history for any supported object. |
| `notifications` | Your notifications. |
| `tags` | Org tags. |
| `statuses` | The status labels defined for a target type. |
| `custom_fields` | The org's custom field definitions: config IDs, types, and the allowed options for select fields. Pass `target_type` to narrow to one object type. |
| `workflows` | Workflow automations. |
| `users` | Users in the org. |
## Reports
`get_report(report_name, ...)` returns cross-cutting aggregations. Each report uses only some of the shared parameters.
| `report_name` | What it returns | Parameters |
| - | - | - |
| `portfolio_risk` | Cross-vendor risk overview. | `top_n` |
| `assessment_metrics` | Completion and throughput over a rolling window. | `days` |
| `evidence_health` | Evidence coverage and gaps. | `vendor_id` |
| `review_queue` | Open findings and in-progress assessments. | n/a |
| `org_activity` | A broad program snapshot in one call. | `days`, `assessment_limit`, `finding_limit`, `radar_limit`, `activity_limit`, `notification_limit` |
| `control_flag_rates` | Controls ranked by how often they flag an issue. The data-driven way to find false-positive-prone controls to tune. | `days`, `top_n`, `min_volume`, `format` |
| `assessment_report` | An executive-ready writeup for one assessment. | `assessment_id` |
| `findings_by_vendor` | Vendors ranked by open finding count. | `top_n` |
| `risk_register` | Risks on your [risk register](/user-guides/risk-register), highest residual first. Every status except closed unless you pass `status` (`proposed`, `open`, `mitigating`, `accepted` or `closed`). | `status`, `domain`, `vendor_id`, `top_n` |
| `risk_simulation` | A what-if scenario over your dependency chain from a plain-English `prompt` (an outage, breach, insolvency, sanction, exit, change, or offboarding). Nothing is saved; the loss estimate is withheld when its inputs are missing. | `prompt` |
`control_flag_rates` accepts `format='csv'` for a spreadsheet-ready export.
## Writes
Every write goes through one tool: `mutate(entity, action, data)`. The per-action parameters go inside `data`.
**Every write requires `confirm: true` inside `data`.** A first call without it returns a confirmation prompt and changes nothing. The assistant is expected to show you the proposed change and wait. See [Roles and permissions](/mcp/permissions#write-protection).
| `entity` | Actions |
| - | - |
| `vendor` | `create`, `update`, `set_tags` |
| `service` | `create`, `update`, `set_tags` |
| `document` | `create`, `update`, `archive` |
| `tag` | `create`, `update` |
| `note` | `add` |
| `finding` | `create`, `update` |
| `obligation` | `create`, `update` |
| `control_set` | `create`, `update` |
| `control` | `create`, `update` |
| `eval` | `update` |
| `assessment` | `start`, `update`, `rerun` |
| `radar_detector` | `create`, `update` |
| `radar_event` | `create` |
| `radar_alert` | `dismiss` |
| `reassessment` | `create`, `update` |
| `custom_field` | `create`, `update`, `set_value` |
| `questionnaire` | `create`, `update` |
| `intake_session` | `create`, `update`, `prequalify`, `suggest_vendors`, `select_vendor`, `upload_document`, `answer`, `submit`, `approve`, `reject`, `request_follow_up`, `archive` |
| `questionnaire_response` | `set_status` |
| `review` | `create`, `update` |
| `contract` | `create`, `update` |
| `engagement` | `create`, `update`, `archive` |
| `rfp` | `draft_brief`, `research_vendors`, `suggest_requirements`, `generate_questions`, `create`, `invite_vendor`, `publish`, `simulate_submissions`, `compare`, `award` |
A few of these carry behaviour worth knowing:
Creating a vendor directly requires `skip_intake: true` in addition to `confirm: true`. Requests to add, buy, or start using a vendor are supposed to go through `intake_session / create` instead, which links or creates the vendor itself. Creating one first leaves a duplicate carrying no due diligence.
The separate flag exists because a generic "yes, create it" is not the same as accepting that due diligence is being skipped.
Editing a control's expectation, evaluation instructions, or evidence requirement changes how the AI judges it. Material edits create a new version rather than overwriting. Pair it with `get_report(report_name="control_flag_rates")` to find the controls worth tuning, and `assessment / rerun` to re-evaluate against the new instructions.
Set `outcome` to `not_an_issue` to clear a false positive, `issue` to flag or reopen one, `mitigated` for a real gap the vendor fixed, or `risk_accepted` for one your organization chose to live with, and attach `review_notes`. Closing an issue does not change the score. This is the per-control correction, distinct from the whole-assessment sign-off in `review / create`.
There is no unarchive.
`draft_brief`, `research_vendors`, `suggest_requirements` and `generate_questions` return proposals and change nothing. `create` is the one write, and it builds the RFP, its rubric, its questionnaire, the vendor records and the invitations in a single transaction. The RFP lands as a draft; no vendor is contacted until `publish`.
A silent RFP researches how each invited vendor would most plausibly answer, from public information. Nobody is contacted, no vendor has agreed to any of it, and every rendering says so. Vendors who already sent a real response are skipped, and a re-run never deletes a real answer.
Setting a value takes a `custom_field_config_id`, and select fields only accept one of their configured option labels. Both come from `query_platform(kind="custom_fields")`.
Writes reject unexpected keys in `data` and return the accepted set. Silently dropping a misspelled `vender_id` would turn a typo into a successful mutation that quietly omits the field you meant to set.
## Discovery
`mcp_capabilities()` takes no arguments and returns a JSON document enumerating every route above with its parameters: name, type, required or optional, and default value.
It's the recommended first call when an assistant isn't sure which route applies, and it's always current, because it's generated from the running server rather than maintained by hand.
## Related
Realistic phrasing for each workflow, and which calls it resolves to.
Twenty scripted workflows you can invoke by name.
How read-only versus read/write is decided, and how it maps to your Coverbase role.
What we log, what we don't retain, and how to revoke access.
# Troubleshooting
Source: https://docs.coverbase.com/mcp/troubleshooting
Common issues when connecting and using the Coverbase MCP server.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
## Connection issues
Confirm your role can connect. Admins, Members, Siloed Members and Guests can; Auxiliary Members and custom roles cannot. See [Roles and permissions](/mcp/permissions#role-to-access-matrix). If only the write tool is missing, the credential is read-only, which is expected for a Guest, a Siloed Member, or a read-only key.
Also confirm the client supports OAuth 2.0 for MCP, not only API-key configurations. Older MCP clients sometimes only support stdio transport, which won't work with the Coverbase server.
The key is almost certainly not reaching the server. A request with no `Authorization` header is answered with `401` and a `WWW-Authenticate` challenge, which every MCP client reads as "start the OAuth flow", so a missing header looks identical to having no key at all.
Check two things:
* Your client config includes `"headers": { "Authorization": "Bearer cb_mcp_..." }`, or `--header` on the command line. A URL on its own is not enough. See [Choosing an authentication method](/mcp/connecting#choosing-an-authentication-method).
* The key starts with `cb_mcp_`. An `ak_` key from **Configuration → API Keys** belongs to the [REST API](/api-reference/api-keys) and is not accepted here; MCP keys come from **Configuration → MCP Server**.
Check that your browser allows pop-ups from the AI client's domain and that you're signed into the correct Coverbase account in the browser session handling the OAuth callback.
If you have multiple Coverbase accounts, sign out of all of them in the browser first, then re-initiate the connection so you're prompted to sign in fresh.
A command-line client such as Claude Code may report an error like:
```text theme={null}
SDK auth failed: HTTP 403: Invalid OAuth error response:
SyntaxError: ... Unrecognized token '<'. Raw body: ... 403 Forbidden ...
```
This happens when something in front of the server returns a raw HTML `403` page where the client expects a JSON OAuth response. The usual cause is a web application firewall that blocks requests with no `User-Agent` header. Command-line MCP clients built on Node send their OAuth and tool requests without one. The Coverbase MCP server explicitly allows header-less requests on the MCP, OAuth, and discovery paths, so on the hosted server this is resolved.
If you still hit it:
* Make sure you added the server with the HTTP transport: `claude mcp add --transport http coverbase https://mcp.coverbase.app/mcp`.
* Update to the latest version of your client and retry.
* If you front the server with your own proxy or firewall, allow requests with a missing `User-Agent` on the `/mcp`, `/oauth/`, and `/.well-known/` paths.
If the error persists, contact [support@coverbase.ai](mailto:support@coverbase.ai) with the client name and version.
## Permission and visibility
The connector enforces your role and permissions. If a record is restricted (for example, an assessment in a restricted folder), it will be invisible to the connector even if you can find it elsewhere in the UI.
Ask your Coverbase admin to confirm the scope of your role.
Search uses partial-name matching but is case-insensitive. Try a shorter query (only the first distinctive word of the vendor name).
If the vendor was recently created or renamed, it may take a few minutes to index. Try again after a short wait.
## Write actions
Every write tool requires `confirm=true`. If the assistant is calling the tool without confirmation, the call returns a precondition error rather than executing silently.
Re-issue the request and approve when the assistant proposes the change. If the assistant isn't surfacing a confirmation step, that's a client behavior issue; report it to your client vendor.
Refresh the affected record in the Coverbase UI. Some object types cache briefly.
Check the audit trail for the record (Vendor → Activity, Assessment → Activity, etc.) to confirm the write was applied. If the audit trail shows the action but the UI doesn't reflect it, report it to support.
## Rate limits and performance
The MCP server sits behind the same request-rate limits as the Coverbase API, counted for each combination of credential and IP address over a one-minute window. A client over the limit gets `403` responses until the window passes, so slow down and retry after a minute.
For production use cases that require higher throughput, contact your account manager.
Some routes (notably `get_report(report_name="org_activity")` and `query_vendors(kind="detail")`) consolidate many internal calls into one to save tokens, which can be slower on accounts with very large data volumes. Try narrower scoping (specific vendor ID, shorter time window).
## Other
Try removing and re-adding the connector. If the issue persists, contact [support@coverbase.ai](mailto:support@coverbase.ai) with a screenshot.
If it speaks MCP with OAuth 2.0 and Streamable HTTP transport, it should work. Let us know what you're using and we'll add it to the test matrix: [support@coverbase.ai](mailto:support@coverbase.ai).
## Status and updates
status.coverbase.com
Tool additions, parameter changes, and deprecations with at least 30 days notice for breaking changes.
## Contact
[support@coverbase.ai](mailto:support@coverbase.ai)
[security@coverbase.ai](mailto:security@coverbase.ai)
[privacy@coverbase.ai](mailto:privacy@coverbase.ai)
# Vendor intake in chat
Source: https://docs.coverbase.com/mcp/vendor-intake
File a complete vendor intake request through an AI assistant: identity confirmation, alternatives, pre-qualification, and the inherent risk questionnaire, without opening the portal.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The vendor intake request a requester normally fills in through the browser portal can be run end to end in conversation. The assistant opens the request, researches the vendor, confirms you have the right company, shows you what you already own that might do the job, runs the screening your org configured, walks the inherent risk questionnaire with you, and submits it to your review queue.
The result is the same intake session (`cbintksn_...`) the portal produces. It lands in the same **Intake** queue, carries the same questionnaire answers, and waits on the same reviewer.
Intake is one of three ways into the same process. The [Intake API](/api-reference/intake) is for embedding intake in another system, the portal is for a requester at a browser, and this page is for chat. All three produce the same session and the same review.
## Starting one
You don't need to know the word "intake". The assistant recognizes the intent from ordinary phrasing:
* "I want to add a new vendor, Marqeta."
* "I want to start using Northwind Analytics."
* "We're onboarding Datadog."
* "Can we buy this? My team needs it for load testing."
* "Run due diligence on Acme."
* "Is Acme approved?"
That last one resolves first: the assistant looks the vendor up, and if there's no approved record, offers to start the intake rather than answering "no" and stopping.
**A new vendor request never becomes a bare vendor record.** Creating a vendor directly would leave a row in your registry with no due diligence attached to it, and a duplicate to clean up later. The assistant routes these to intake instead. If you genuinely want a record with no diligence, say so explicitly, and the assistant will tell you what you're giving up before it creates one.
## What the assistant does
From the vendor name alone. You are not interrogated for a use case first, because the assistant can offer you real choices once it has researched the vendor. If the name matches vendors you already have, it shows you the candidates and asks which one, rather than guessing or silently creating a new vendor.
Before running anything. Your intake portal decides which steps exist, and the assistant reads that first so a step your org turned off is never run in the first place. See [Your configuration is the script](#your-configuration-is-the-script).
What the company does, its website, its headquarters location, its trust center, and the match confidence. You get that profile and confirm it's the right company before anything else happens. Two vendors called Acme is the ordinary case, not the edge case, and a request filed against the wrong one wastes a full review cycle.
Existing vendors in your portfolio that do the same job, prior relationships with this vendor, and alternatives found on the web, to the extent your portal enables each. If something already approved covers this, you're told before you commit, not after the request is filed. Catching the duplicate purchase is what intake is for.
Not as blank questions. You get a numbered list of what this vendor is bought for, drawn from the research, and another of the candidate services in scope. Every menu takes an answer that isn't on it, so you're never forced into a choice that doesn't fit.
Pre-qualification (financial stability, security posture, sanctions) and the duplicate check run as part of the flow, and the assistant reports what came back. It still asks your go-ahead before each write. The difference is that it tells you what happens next instead of asking whether to bother. Only a *failed* screen is handed back to you as a decision.
Coverbase's AI answers what it can from the context you gave and public sources, the same background process the web intake uses. This takes a moment; the assistant waits for it.
Each drafted answer arrives marked **AI draft, needs confirmation**, with the reasoning behind it. You accept, correct, or replace it. The questionnaire is not optional and the assistant won't offer to skip it; if you stop partway, it tells you the request stays incomplete.
Which fails if a required question is still unanswered, and moves the request to pending review.
## Submitting is not approval
Filing an intake request is not permission to buy, sign, or deploy anything.
At the end of the flow a vendor record may exist in Coverbase, but it sits in **Created** status. It is not an approved vendor. Your security or due diligence team reviews the submitted request and decides it, and only that decision authorizes use.
A well-behaved assistant says this explicitly when it closes out the flow rather than leaving you to infer it from a green checkmark. If yours ends an intake in a way that reads like approval, that's worth reporting to us.
## Your configuration is the script
The steps above are not hardcoded. Your organization's intake portal decides which of them exist, and the assistant reads that configuration before it runs anything.
| Portal ask | What it enables in chat |
| - | - |
| **Vendor search** | Vendor matching, existing-vendor alternatives, web alternatives, and prior assessment history. Each is separately switchable. |
| **Prequalification** | Financial, security, and sanctions screening. Each check is separately switchable. |
| **Questionnaire** | The inherent risk questionnaire attached to the intake. |
| **Document upload** | Attaching supporting evidence to the request. |
An ask you removed means the step is off, and the assistant will not reintroduce it in conversation. If your org turned off web alternatives, or prior assessment history, or pre-qualification, chat honours that. This matters because a chat interface is otherwise easy to talk into doing extra work you deliberately disabled.
If the assistant runs a step you don't expect, ask it what your portal configuration reports. It can read the enabled and disabled steps back to you directly.
## Every write asks first
Opening the request, recording an answer, running pre-qualification, and submitting are all writes, and every one of them requires your explicit approval before it executes. The assistant proposes the change in chat and waits.
This is the same human-in-the-loop rule that applies to [every write tool](/mcp/overview) on the MCP server. Intake is not exempt from it, and the guided flow doesn't turn into an autonomous one.
## What still needs the app
Two question types have no sensible chat representation and report themselves as app-only:
* **Contact questions**, whose answer is a structured person record.
* **Document-upload question types**, which need a file picker.
The assistant gives you a deep link to finish those in Coverbase. Everything else completes in the conversation.
## Reviewing what comes in
The other half of intake is the reviewer's, and it also runs in chat. The assistant can walk your pending-review queue, summarize each submission with its enrichment and screening results, and approve, reject, or request follow-up, each with confirmation.
Reviewers who prefer the dashboard lose nothing: sessions filed through chat appear in the **Intake** queue exactly as portal submissions do.
## Prompts
The server ships canned prompts that script these flows, so you can invoke one instead of describing what you want:
| Prompt | What it does |
| - | - |
| `submit_intake_request` | Files a new vendor intake request end to end. |
| `triage_intake_queue` | Walks every pending-review intake session. |
| `review_intake` | Approves, rejects, or requests follow-up on one session. |
| `onboard_new_vendor` | Adds a bare vendor record with no due diligence. Only when you explicitly want to skip intake. |
Realistic phrasing for each of these, and what the assistant does with it.
## Related
The REST path: create sessions programmatically and poll for generated answers. For embedding intake in procurement or ticketing.
The product: classification, assessment plan selection, and downstream workflow orchestration.
Set up Claude, Cursor, VS Code, or any MCP client against the Coverbase server.
What the connected assistant can see and do, and how that maps to your Coverbase role.
# Agent Ledger and AI governance
Source: https://docs.coverbase.com/products/agent-ledger
A record of every action an AI agent takes on your data, the policies that say what agents may do without a person, personal data redaction before model calls, and calibration from your own reviewers' corrections.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Your Coverbase representative turns on the third-party lifecycle features, including the Agent Ledger, for your organization.
The **Agent Ledger** page under **Configuration** answers the questions an auditor, a model risk team or a regulator asks about AI in your program: what did an agent do, to which record, based on what, how sure was it, which models did it call, and what did a person decide. Beside the ledger sit your organization's AI settings.
## What it does
Which agent, what it did, to which record, what it read, what it cited, its confidence, the models it called and how many personal details were redacted. A person can accept, edit and accept, or reject an action, one at a time or in bulk.
What agents may do without a person, enforced where the agent acts. Re-timing monitoring from feed signals (off by default) and proposing diligence reuse (on by default) are live. Accepting risk or closing an issue always needs a person and cannot be switched on.
Off by default. When on, email addresses, phone numbers, IBANs, US tax IDs and the names of your users and your vendors' contacts are replaced with placeholders before a request reaches the model, and put back in the answer before anyone sees it.
When a reviewer overturns a control evaluation, the correction becomes an example for that control. Nothing reaches an evaluation until you turn learning on, and you can switch any example off.
**Export for audit** writes the actions matching your filters, up to 50,000, to a CSV in the background, with citations, models, the redaction count and the human decision.
## What is recorded today
These agents write to the ledger: control evaluation, vendor matching and question planning during intake, follow-up suggestions, the [Intake Agent](/products/intake-agent) reading a request from a message, questionnaire drafting in the portal, document analysis, the Zero Touch automated review, contract clause review, [claim checks](/products/claim-check), the risk report narrative, and Radar signal summaries.
## Agent policies
A policy is checked where the agent acts, against the current setting, so a policy switched off a moment ago holds.
| Policy | What the agent does | With the policy off |
| - | - | - |
| **Re-time monitoring from feed signals** (off by default) | Moves monitoring plan activities forward when a Radar alert or reassessment trigger fires. Each moved plan gets a row reading **Applied under org policy**. | Nothing moves. One row per vendor and signal reads **Held back by org policy**. |
| **Propose diligence reuse** (on by default) | Picks the similar engagement inside the reuse window that the Front Door starts reviewers from. Recording the disposition writes a row with the reviewer's acceptance or rejection. | No proposal. Reviewers start from full due diligence and still see every match. |
**Auto-close low tier reassessments with no changes** and **Send anything to a vendor without review** have no agent behind them yet, so they stay off and cannot be switched on. **Accept risk or close an issue** always needs a person.
Writing a ledger row never fails the action it records. A failed action is recorded as **Failed**.
## How redaction works
Redaction runs in the connection to the model provider, not in individual features, so every model call your organization makes passes through it. If Coverbase cannot read whether redaction is on for your organization, the call fails rather than going out unredacted. Placeholders look like `[[PERSON:1a2b3c4d5e6f]]`. Each is a keyed hash under a secret held for your organization, so the same person gets the same placeholder across calls and a placeholder cannot be reversed by guessing. Only placeholders the redactor issued are restored.
Redaction covers the text of a request. It does not reach inside images or attached documents, such as a PDF sent to the model as a document, or a file the model provider reads directly from storage. Bank and tax identifiers stored on supplier records are sealed per field and never reach a prompt in clear, whether or not redaction is on.
A model request type that redaction does not cover fails while redaction is on, so a new kind of call cannot bypass it.
## How learning works
A daily job collects every evaluation a reviewer moved across the issue boundary in the last 180 days, in either direction, as a learned example for that control. With learning on, a control's evaluation gets up to five of its enabled examples and your organization's evaluation guidance, marked as reference data. With learning off, evaluations use the baseline prompt unchanged. Learning applies to your organization only.
## Where to go next
Read the ledger, record a decision, set policies, turn on redaction and learning, and export.
How Coverbase selects, tests and constrains the models behind these agents.
How assistants connected through MCP are logged and constrained.
Encryption, field-level sealing and tenant isolation.
# Agentic Inspect
Source: https://docs.coverbase.com/products/agentic-inspect
Agentic, browser-based vendor inspection that converts attestations into verified control evidence.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Inspect performs structured discovery using a headless browser. It works against two surfaces: a **vendor's** public and authenticated surface area, where it validates attestations and extracts evidence from trust centers; and **your own application tenants**, where it signs in and reads the live admin console to collect evidence for a chosen set of controls. Either way it captures screenshots and artifacts with full chain-of-custody metadata.
## What it does
Parse vendor trust centers (Drata, Vanta, SafeBase, custom portals) to extract published controls, certifications, and evidence references.
Convert claims into verified evidence by retrieving the vendor's published attestation pages and audit reports directly.
Record screenshots, source URLs, timestamps, and request metadata for every artifact so audit trails are defensible.
Sign in through Okta or Microsoft Entra SSO, a Google account, or a username and password, answering one-time codes and passkey prompts, so Inspect can reach evidence behind a login. For a gated vendor trust center, the agent fills in the access request form.
## Inspecting your own applications
The other half of Inspect points at the applications *you* run. Rather than asking a vendor whether MFA is enforced, Inspect signs in to the tenant and reads the answer off the admin console.
An **inspection** is one request against one target, with one control set and one purpose. Inside it, each control gets its own **control run**, so one control failing to collect evidence never stops the rest.
Establish whether the evidence a control needs can be collected from this application at all. Run this first against an unfamiliar tenant.
Adjudicate the evidence against the control expectation and your scale. This is the run that produces a judgment.
Compare against a compatible earlier inspection, so a setting an administrator changed since the last run surfaces as a difference.
Control sets come from the [Internal Controls Library](/control-library#internal-controls-library): 22 templates spanning 392 controls, covering identity, privileged access, integrations and OAuth, data handling, PII, PHI, GDPR, AI features and agents, resilience, SLA conformance, audit logging, and licensing, plus a CIS Controls v8.1 SaaS baseline.
Re-run on a cadence and **Drift** turns point-in-time evidence into continuous assurance: each comparison reports `exact`, `changed`, or an explicit reason it could not be compared, and a change is judged material, immaterial or inconclusive with a summary of what differs. A material change sends an alert to whoever requested the inspection, and an issue an Evaluate run raises becomes a finding, on the same Findings page as everything else, when you create one from it. See [Internal control monitoring](/products/internal-controls-monitoring) for how that joins up with third-party risk.
**Absent evidence is reported, never omitted.** An observation that could not be obtained still exists and still says why: unsupported, authentication required, forbidden, inconclusive, or failed. An application that does not sell a capability is not marked down for lacking it.
Progress and outcome are separate facts. "5 of 5 controls finished" says nothing about whether any of them passed, so read the status rather than the count.
## How to integrate
Inspect accepts inspection plans and returns structured findings suitable for ingestion into an assessment record.
Specify target domains, evidence types, and auth context for each plan.
Results return as structured records that map directly to Coverbase evaluations, with citations and captured artifacts attached.
## Common workflows
Instead of emailing a vendor for proof of encryption at rest, Inspect pulls the relevant section from their SOC 2 in the trust center, captures it with chain-of-custody metadata, and attaches it to the evaluation.
When a reassessment collects documents automatically, the agent retrieves the vendor's trust center documents again, so an updated SOC 2 or a lapsed certification is what the new evaluation reads.
Retrieve the vendor's trust center documents before sending a questionnaire. Controls the documents already answer are evaluated from them, and follow-up questions go to the vendor only for the gaps.
## Related
Running Inspect against your own applications, and how internal and third-party risk share one model.
The internal and vendor control sets Inspect evaluates against.
# Assessment Copilot
Source: https://docs.coverbase.com/products/assessment-copilot
AI-powered assessment engine that automates approximately 90% of vendor risk assessment workload.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Assessment Copilot replaces manual, spreadsheet-driven workflows with a programmatic pipeline. It generates custom questionnaires, extracts controls from uploaded evidence, evaluates vendor responses, and drafts follow-ups for the gaps, routing the cases the evidence cannot settle to human reviewers.
## What it does
Generate vendor questionnaires scoped to the control sets you care about, the vendor's risk tier, and the services in scope.
Parse SOC 2 reports, ISO certifications, pen test summaries, and policy documents to extract control evidence automatically.
Evaluate every control against the vendor's answers and documents, flagging weaknesses as issues and marking what the evidence cannot settle for review rather than guessing.
Draft targeted follow-up questionnaires from the issues an assessment raises, flag residual risk for reviewer attention, and schedule the next reassessment from the vendor's risk level.
## Evidence quality controls
Copilot researches the public web when a control can't be answered from the documents on file. That evidence is not taken on trust: every candidate page is graded for **publisher accountability** (Unreliable, Reputable, or Authoritative), and anything below the minimum you configured is discarded before the evaluating model sees it. Accepted citations carry their grade, the reason for it, and the page's age at the time it was cited, both in the UI and in the Excel export.
The full guide: the grading scale, where to set the minimum per control set or per control, how the bar is enforced, and what it does and doesn't cover.
## How to integrate
Copilot is exposed across both API surfaces:
Pull assessment results, evaluations, and findings into your compliance dashboards or regulatory reporting pipeline.
Drive assessments from a conversational interface. Start a new assessment, summarize results, or find controls that need human review.
## Common workflows
Wire Copilot into your vendor onboarding flow. When a new vendor enters intake, trigger a Copilot assessment scoped to the appropriate control set and tier. Pull results via Export API and surface them in your procurement system before contract execution.
Schedule reassessments on a recurring cadence for each risk level (annual, semi-annual, or any interval), or trigger one from an event such as a Radar alert or a jump in the vendor's risk score. Each reassessment evaluates the controls again against the latest evidence.
Set each control set's strictness to decide how much the evaluation may infer on the vendor's behalf, and route assessments to named reviewers for approval. An evaluation the evidence cannot settle is marked for review rather than guessed, and issues surface for a person to accept, dismiss or follow up.
Copilot is part of the Coverbase platform and is accessed through the Export API and MCP server rather than a dedicated endpoint. See the [Export API Concepts](/export-api-concepts) page for assessment and evaluation base objects.
# Autonomous Intake
Source: https://docs.coverbase.com/products/autonomous-intake
Vendor intake that researches the vendor, catches duplicate spend, screens it, and drafts the risk questionnaire, then routes every request into the TPRM program at the correct depth.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Autonomous Intake removes the manual routing layer between procurement and risk teams. A requester says what they want; Coverbase identifies the vendor, checks whether you already pay for something that does the job, screens the company, drafts the inherent risk questionnaire, and puts a complete request in front of a reviewer. Every engagement enters the TPRM program at the correct depth, and the requester spends minutes rather than an afternoon.
## What it does
Accept submissions in their natural form (requester context, vendor identity, intended use, data types) without forcing a rigid form structure.
Identify the company from a name: what it does, its website, its headquarters, its trust center. The requester confirms the match before anything else runs, so a request is never filed against the wrong Acme.
Rank your existing vendors against the request and surface prior relationships, so a second tool for a job an approved vendor already covers gets caught before the spend, not during review.
Screen financial stability, security posture, and sanctions exposure as part of the flow. Screening can be turned off per intake portal, and a vendor that doesn't clear is surfaced to a human rather than auto-rejected.
Answer the inherent risk questionnaire from public sources and the context supplied, with per-answer confidence and the reasoning behind each. The requester validates rather than types.
Score each request's inherent risk from the questionnaire answers (data sensitivity, criticality, engagement type) and band it on your risk scale, overall and per risk domain. Drives which controls apply.
When a reviewer approves the request and launches an assessment, the assessment plan's rules pick the control sets from the inherent risk score, the per-domain scores, and tags, including any custom control sets layered on your baseline standard.
Trigger workflow automations when a request is submitted or approved, so the assessment, the contract, and downstream tickets follow without a manual hand-off.
## Three ways in, one process
A request can arrive three ways. All three produce the same intake session, obey the same configuration, and land in the same reviewer queue.
A requester fills in the browser form: select vendor, add information, review questionnaires.
`POST` a free-form payload from procurement or ticketing and poll for the generated answers.
An AI assistant runs the whole request conversationally through the MCP server.
## You decide which steps run
Intake is configuration, not a fixed script. Your intake portal decides which steps exist, and every surface honours it, including chat, which will not reintroduce a step you deliberately turned off.
| Step | What you control |
| - | - |
| Vendor search | Matching against your existing vendors, web alternatives, and prior assessment history, each separately switchable. |
| Pre-qualification | Whether financial, security, and sanctions screening runs, and whether sanctions are checked with [Coverbase sanctions screening](/user-guides/sanctions-screening#screen-a-vendor-at-intake) or the OFAC list. |
| Questionnaire | Which questionnaires attach to the intake. |
| Document upload | Whether supporting evidence is collected at intake. |
## Submitting is not approval
A completed intake request is a request, not permission. A vendor record created through intake sits in **Created** status; it is not an approved vendor until a reviewer decides the request.
This is the point of the product. The requester gets a fast, guided path and a clear answer about what happens next; the risk team keeps the decision.
## Common workflows
A requester asks an AI assistant for the tool they want ("I want to start using Northwind Analytics"), and the assistant runs the request: confirms the vendor's identity against research, surfaces existing vendors that already cover the need, runs the screening the portal configures, and walks the inherent risk questionnaire one question at a time. No form, and no requester who has to learn the word "intake". See [Vendor intake in chat](/mcp/vendor-intake).
Call the [Intake API](/api-reference/intake) from your procurement or ticketing system. When a requester opens a new vendor request there, the request's free-form context becomes an intake session, and Intake researches the vendor and drafts the questionnaire before a reviewer sees it.
Use the classification to drive approval routing. Tier 1 vendors loop in CISO and Legal; Tier 4 SaaS tools follow a lightweight path. The same intake form, different downstream depth.
Let requesters submit through a simple form. Intake handles classification, reviewer assignment, and follow-up questions to the requester so risk teams aren't the bottleneck.
Requests arrive pre-enriched with the screening results, the duplicate readout, and the auto-answered questionnaire. Reviewers validate rather than research, and can approve, reject, or send a request back with a specific question. This works in the dashboard or in chat.
## Guides
For the business requester: what you'll be asked, how to file it, and what happens after you submit.
For the risk team: triaging the queue, reading the enrichment, and validating auto-answered questions.
Autonomous Intake is configured in the dashboard and exposed programmatically through the platform API. See the [Intake API reference](/api-reference/intake) for creating intake requests with free-form context. Talk to your account manager about API access if it's not yet enabled on your plan.
# Certificate Vault and prequalification
Source: https://docs.coverbase.com/products/certificate-vault
One repository for every certificate a vendor holds, whether uploaded, read from a document, pulled from ISNetworld, Avetta or EcoVadis, or found in a trust center, with prequalification rules that can block new purchase orders and licensed security, financial and credit ratings in Radar.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Your Coverbase representative turns on the third-party lifecycle features, including the Certificate Vault, prequalification, and the licensed rating connectors with their Radar rating detector, for your organization.
The Certificate Vault is a record for every attestation your program relies on: ISO certificates, SOC reports, PCI attestations, certificates of insurance, network grades and ESG ratings. Prequalification rules read the vault to decide which vendors may be used, and licensed rating providers feed rating changes into Radar.
## What it does
**Certificates** in the left navigation lists every certificate across your vendors, and each vendor has a **Certificates** tab. Validity (valid, expiring within 60 days, expired) is worked out when you look, so it never goes stale.
Certification, PCI, SOC 1 and SOC 2, ACORD 25 and insurance policy documents fill the vault when they are analyzed. Trust center documents, network pulls and certificates you add by hand fill it too, and you can request a certificate from the vendor through the supplier portal.
Rules that must all pass, each passing when any one of its conditions does: a network grade, a network status, a certificate held, insurance coverage with a minimum limit and additional insured, or a safety or ESG figure such as TRIR, EMR, DART rate or ESG score.
A rule set can block new purchase orders until the vendor qualifies or someone records an override with a rationale. An override lapses when the result changes.
ISNetworld and Avetta grades, safety statistics and insurance, and EcoVadis scorecards, sync into the vault daily.
Bitsight, SecurityScorecard, RapidRatings and Moody's ratings are pulled for your portfolio. A change in a matched vendor's rating becomes a Radar signal, and the first pull is a baseline, so connecting a provider does not flood Radar.
When a provider's response does not have the shape Coverbase expects, the pull stops and records the error rather than reading it as empty, so a changed response never archives certificates. A value the provider reports as zero, such as a rating, a score, an insurance limit or a company ID, is recorded as zero.
## How long a certificate counts
* A SOC report is relied on for a year past the end of its period.
* A certificate of insurance is only as current as its first policy to lapse.
* Every prequalification condition reads only current certificates, so an expired record stops counting for its grade and its figures alike.
* A safety figure over a number of years needs each of the latest years reported. A missing year fails the condition.
## Where prequalification shows up
* On the vendor's page, as **Qualified**, **Blocked** or **Overridden**, with **Override with rationale**.
* On the Front Door review of an intake request, with the same override control.
* When someone issues a purchase order in Coverbase for a blocked vendor: the purchase order is refused.
* In workflows, as a prequalification condition you can branch on.
A failing rule set that does not block reads as advisory. Results are recalculated when a certificate changes, when you save a rule set, and once a day. Each rule set can remind relationship owners a set number of days before a certificate lapses.
## Where to go next
Fill the vault, write a rule set, override a result and connect a network.
Connect contractor grades, statistics and insurance.
Bring security rating changes into Radar.
Where rating changes become signals.
# Claim check
Source: https://docs.coverbase.com/products/claim-check
Test each vendor questionnaire answer against the evidence the vendor already gave you: SOC reports, certifications, trust center documents, the outside-in scan, licensed ratings and contract terms. Every verdict cites the passage it rests on.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A vendor's questionnaire answer is a claim. Claim check reads the evidence you already hold on that vendor and says, for each answer, whether the evidence supports it, contradicts it, cannot settle it, or says nothing about it. It runs in the background on a questionnaire submission and appears on the submission's **Claim Check** tab.
Your Coverbase representative turns on the third-party lifecycle features for your organization.
## The four verdicts
| Verdict | Meaning |
| - | - |
| **Supported** | The evidence on file establishes what the answer claims. |
| **Contradicted** | The evidence on file says something the answer cannot be true alongside, such as an exception the auditor noted. |
| **Needs evidence** | The evidence speaks to the topic, but neither proves nor disproves the answer. |
| **Not covered** | Nothing on file speaks to the answer. |
Every verdict except **Not covered** carries the passages it rests on, with the source, the page and the quoted text highlighted.
## How a verdict is reached
* **The model proposes, code decides.** A model reads each answer with the most relevant evidence (between four and ten items) and proposes a verdict with quotes. Code then checks every quote against the source text. A quote that cannot be found in the source is dropped, and a **Supported** or **Contradicted** verdict with no quote left falls to **Needs evidence**, with its confidence capped.
* **Authority comes from the kind of evidence, not the model.** Auditor's reports, accredited certifications, independent assessments, the outside-in scan, licensed ratings and executed contract terms are **Authoritative sources**. Vendor policies, trust center pages and draft contract terms are **Vendor's own statement**. An authoritative contradiction outweighs a vendor's own statement that agrees, so a trust center page cannot clear a SOC 2 exception.
* **One verdict per answer.** Checking again replaces the verdict. When an answer changes after it was checked, the verdict shows **Answer changed** until it is checked again.
* **Recorded in the Agent Ledger.** Every model call is a ledger row, with personal data redaction applied when your organization has it on.
## What you can do with a verdict
* **Raise finding with this evidence**: one finding per question, narrowed to the question and carrying the answer, the verdict and the cited evidence. Answers that already have an open finding are skipped.
* **Ask vendor to clarify**: a message on the vendor's portal request, attached to the question. The vendor sees which question a message is about only when their own form on that request asks it.
* **Check again** on selected answers.
Each bulk action reports what it did and what it left alone, for example "3 findings raised, 1 already had a finding".
## Where to go next
Run a check, read the verdicts and act on them.
The rest of the due diligence workbench.
How source credibility is graded.
Where each check is recorded.
# Clause packs and non-standard contracts
Source: https://docs.coverbase.com/products/clause-pack
Turn an engagement's risk results into the contract clauses it requires, see whether the draft carries each one, monitor the obligations in the signed contract, and list every non-standard clause across your contracts.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A clause pack turns an engagement's due diligence results into the contract clauses that hold the vendor to controlling the risk. Your legal team maps clauses to risk domains once. For each engagement, Coverbase then lists the clauses its risk results and open issues require, shows whether the current draft carries each one, and, once the contract is signed, turns the obligations those clauses carry into activities on the engagement's monitoring plan.
Your Coverbase representative turns on the third-party lifecycle features for your organization.
## What it does
On a reference clause in **Clause Sets**, **Required by Risk Domain** names the risk domain and minimum level that require it, optionally also whenever the domain has an open issue, and what to monitor after signing.
The engagement's **Contract** tab lists each required clause, why it is required (for example **Privacy · High** or **Open issue**), and whether the draft has it: **Present**, **Missing**, **Non-standard**, **Added to redline** or **Not reviewed**.
An open issue with a remediation due date adds a covenant to the pack, so the contract holds the vendor to the fix.
When the contract is signed, each required clause that made it into the contract and carries an obligation becomes an evidence request or scorecard activity on the monitoring plan, on its cadence. Event obligations are watched through Radar and issues instead.
Every clause whose latest review found it non-conforming, missing or needing review, across all contracts, filterable by severity, status and risk domain, and exportable as CSV.
## The rules it follows
* **The pack reads what the Risk Summary reads.** It uses the same domain results (residual where there is one) and the same open issues, so the pack cannot disagree with the decision it follows.
* **Clause review decides what the draft says.** The draft state comes from the latest complete [Contract Guardian](/products/contract-guardian) review of each contract linked to the engagement. The pack only marks a clause for the redline.
* **Rebuilding never drops a signed obligation.** A clause no longer required leaves the pack, unless it is already in the signed contract.
* **Only signed clauses are monitored.** At signature, a clause the draft held or that was added to the redline counts as signed. One still missing or non-standard does not, and its obligation is not monitored.
## Where to go next
Map clauses to risk domains, build a pack and read the report.
The clause review the draft state comes from.
Where signed obligations are monitored.
The Risk Summary the pack follows.
# Contract Guardian
Source: https://docs.coverbase.com/products/contract-guardian
Contract analysis, clause review, and redline surfacing for third-party agreements.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Contract Guardian extracts clauses, detects missing clauses, analyzes liability and indemnity, surfaces AI-usage provisions, and flags deviations from an organization-defined playbook. Rerun it against amendments and addenda so the contractual control surface stays aligned with the live risk profile maintained in Supplier Radar.
The core idea: you write down your standard once, as tiers of acceptable language. Coverbase then finds the vendor's version of each clause, decides which tier it lands in, and gives your reviewer a short list of deviations with the source text quoted and highlighted, instead of an agreement to read end to end.
Guardian decides which clauses deviate and how far, then marks the asks up for you. It does not negotiate. A person reviews the marked-up file and decides what to send.
## What it does
Parse MSAs, DPAs, SOWs, BAAs, and order forms to extract clauses, terms, and obligations into structured records.
Compare extracted contracts against your playbook and flag clauses that should be present but aren't (data breach notification, audit rights, subprocessor flow-down).
Surface liability caps, indemnification scope, and limitation-of-liability language so legal teams can focus review on what deviates from standard.
Detect AI-specific clauses, model training restrictions, output ownership, customer data usage in model improvement, and flag where they're missing.
## Clause sets and risk tiers
A **clause set** is your playbook. Each **reference clause** in it is one standard you hold vendors to, carrying a severity, guidance that tells the matcher how to find the clause, the contract components it applies to, and a set of **variants**: versions of the clause language at different levels of acceptability, tiered 1 to 5.
Coverbase matches the vendor's actual language to the closest variant, and the tier drives the verdict:
| Risk tier | Meaning | Clause state |
| - | - | - |
| 1-2 | Preferred or acceptable | **Conforming** |
| 3 | Negotiable, warrants a look | **Needs review** |
| 4-5 | Materially worse, or unacceptable | **Non-conforming** |
Sets copied from the packaged library are scored against a target tier instead, so a vendor meeting or beating the ask conforms. Two guardrails sit on top: a low-confidence match is escalated to **Needs review** rather than auto-passing, and language found outside the components a clause was scoped to is escalated the same way. Where no language is found, the result is **Missing** when the relevant component is present in the contract, and **Not applicable** when it isn't.
### Three ways to build one
Copy one of 12 packaged templates, from Enterprise SaaS to HIPAA to Payments: 311 reference clauses between them, each with four tiers of language already written. Your copy is fully editable.
Upload your template MSA or DPA as a baseline contract, or your negotiation playbook with its preferred and fallback positions. Guardian builds the clause set from the exact language in your document. A playbook kept in a spreadsheet imports directly.
Author reference clauses directly for narrow, high-stakes standards. Clauses are versioned, so edits never rewrite the history of reviews already run.
## Review and triage
Guardian first detects the logical components inside the linked documents (MSA, DPA, order form, SLA, NDA, SCCs, AI addendum, amendments), then evaluates each reference clause only where it belongs.
Each result carries the extracted vendor language, the matched variant, a confidence score, the source document and page, and highlighted evidence in the PDF.
Where the vendor has a completed assessment, flagged clauses are cross-referenced against that evidence and given a suggested disposition (no action, revise language, add clause, or escalate) with citations back into the assessment.
Reviewers mark each flag as no action, accepted risk, or false positive, or escalate it to a tracked finding. The system verdict and the human decision are both preserved on the record.
Select the deviations worth pushing back on and generate an outbound follow-up draft built from those specific clauses. Nothing sends automatically: copy it, open it in the email composer addressed to the vendor with the redline attached, or escalate to a finding.
Where the contract arrived as a Word file, download it back with the vendor's wording struck and your playbook's inserted as tracked changes, plus a comment per clause carrying the ask. It opens in the Review ribbon the vendor already uses.
## Draft versioning and redline history
A contract is a family of documents, not a file, and Guardian is built on that model. Drafts, redlines, executed originals, amendments, restatements and exhibits are all held together and ordered, so "what did we agree, and how did we get here" is answerable without opening six PDFs.
Coverbase draws a typed relationship between any two documents in a family: **amends**, **restates**, **attaches to**, **redline of**, and **duplicate of**, each recorded with the evidence that produced it. A version chain is data, not a naming convention.
A marked-up draft is detected from its tracked changes and its content, and routed to the **redline and negotiation history** component. It is kept for the record, and it is **never in force**: an unsigned Net 45 draft can never compete with the signed Net 60 amendment for the payment-terms slot.
Amendments resolve as an ordered series where each supersedes the last, with the effective date deciding. A superseded instance stays visible in the history rather than being deleted, and anything contributing nothing in force, a redline or a duplicate, renders struck through.
Each resolved term names the document, the page and the effective date it came from: "Net 60, from Amendment 3 effective 1 Jan 2024, supersedes Net 30 in the master agreement." You can open the source span from the answer.
Two further version-history properties matter for legal review:
* **Conformed copies are handled deliberately.** A master re-issued with its amendments already incorporated is recognized as such, and you choose whether the absorbed amendments stay as separate terms or are marked incorporated. Counting the same amendment twice is the failure mode this exists to prevent.
* **Clause sets are versioned.** Editing a reference clause never rewrites the history of reviews already run against the previous wording, so a review from last quarter still shows the standard it was judged against.
### The review's own history
Alongside the document lineage, each Guardian run keeps its own record: the system verdict per clause, the matched variant and tier, the confidence, the evidence with page citations, and the human triage decision layered on top. Re-run Guardian after an amendment and you get the new verdict beside the old one, so what changed in the controlled obligation surface is visible rather than inferred.
Where the contract arrived as a Word file, Guardian can return it with the counterparty's wording struck and your playbook's inserted as tracked changes, plus a comment per clause carrying the ask. It opens in the Review ribbon your counterparty already uses, which keeps the negotiation in the format legal teams redline in.
## How to integrate
Submit contract documents (PDF, DOCX) for analysis. Returns structured clause extraction and playbook deviation report.
Add amendments and addenda to the contract and rerun the review against the existing paper, surfacing what changed in the controlled obligation surface.
## Common workflows
Submit drafts to Guardian before legal review. It surfaces deviations from your playbook, missing clauses, and unusual liability terms so reviewers focus on the deltas rather than reading every contract end to end.
Bulk-process your existing contract portfolio. Guardian extracts obligations, surfaces gaps against your current playbook, and produces a prioritized list of contracts that need renegotiation.
Guardian-extracted obligations feed the Coverbase obligation surface, where they can be assigned, tracked, and linked to controls. When a vendor's risk profile changes in Supplier Radar, contractual obligations are already in scope.
Pair clause review with [Document Insights](/products/document-insights) to populate the contract record itself: value, term dates, notice periods, liability caps, and governing law extracted from every document with page citations.
Setting this up? The [Contract Guardian guide](/user-guides/contract-guardian) walks through building a clause set, writing risk-tier variants, and running your first review. Contract Guardian results integrate with the Coverbase obligation and finding surfaces, accessible through the [Export API](/export-api-concepts) and [MCP server](/mcp/overview).
# Corporate Registrations
Source: https://docs.coverbase.com/products/corporate-registrations
Validates the legal entity behind a vendor against public business registers, with a citation for every fact.
Most vendor records start life as a name and a website. **Corporate Registrations** answers the question that sits underneath every other piece of diligence. Is there a real, currently registered company behind this, and is it the one we think it is?
It runs automatically once a vendor has a website on file, and appears as the **Registrations** tab of a vendor's **Vendor Intelligence** section.
## Where the data comes from
All sources are public. Companies House needs a free key, which Coverbase configures.
| Source | What it contributes |
| - | - |
| **GLEIF** | The authoritative legal name and LEI, entity and registration status, jurisdiction, legal and headquarters addresses |
| **OpenCorporates** | Company number, jurisdiction, incorporation date, current status, and a link back to the originating registry |
| **The vendor's own legal pages** | The contracting entity, its former names, its subsidiaries and its registration numbers, quoted from its terms, privacy policy, imprint and footer |
| **Companies House** | Every UK company, private ones included: company number, status, incorporation date, registered office, and corporate owners |
| **SEC EDGAR** | US public-company validation: CIK, ticker, state of incorporation, industry classification |
| **Dun & Bradstreet** | DUNS number, surfaced when your organization already has D\&B credentials |
## Read the verdict first
The page leads with a match decision rather than with identifiers, because every identifier below it is only meaningful once you know they belong to *this* vendor.
A registered company was bound with high confidence. The identifiers can be relied on.
Something plausible was found but not confirmed. Two companies sharing a trading name in one jurisdiction is the usual cause. Check the identifiers before using them.
Nothing credible matched. Common for very small, very new, or non-corporate suppliers.
A match confidence accompanies the decision. Treat it as a measure of binding certainty, meaning how sure we are that these records describe your vendor. It says nothing about the company's health.
When no register holds the entity but the vendor names it on its own legal pages, the page shows that entity as **Identified from the vendor's own pages**, with the quotes. When several registered companies share the vendor's name, the page lists them as **Possible matches** for you to pick from.
To fix a wrong or missing entity, use **Correct with AI**: describe the right entity in your own words, see the match, and apply it. Your correction is kept for every later refresh. See the [Corporate registrations guide](/user-guides/corporate-registrations#correct-with-ai).
## What the page shows
LEI, company number, SEC CIK and DUNS. These are the registry keys that let you look the company up independently, anywhere else.
Whether the company is currently active, dissolved or inactive; its jurisdiction; incorporation date; whether it is publicly listed and under what ticker; and its industry classification.
A **dissolved** status on a vendor you are actively paying is one of the highest-signal findings in the product. It usually means a restructure nobody told you about, or that you are contracting with an entity that no longer exists.
The registered and headquarters addresses on file with the registers. These frequently differ from the trading address a vendor gives you, which is normal and not itself a finding.
The vendor's parents and subsidiaries, from GLEIF's relationship records, Companies House's corporate owners, and the entities the vendor names on its own pages. Each entity says whether a register holds it or only the vendor names it.
Every register checked and the identifier it returned, each linking back to the source record. Citations are listed per lookup rather than collapsed to one row per register, so it stays visible which fact rests on which record.
Caveats recorded while matching: why a candidate was rejected, or why two remain in contention.
## How it's used elsewhere
Corporate registration data feeds:
* **Financial Health Score.** Corporate standing is one of the scored pillars, and registry identifiers are how a vendor is resolved to filings in the first place.
* **Zero Touch Assessments.** Registration validation can be included as a scored component of the composite.
* **The vendor fact sheet.** The validated legal name and status appear in the company profile.
A missing registration record is not a red flag on its own. Sole traders, partnerships, and vendors in jurisdictions with no open registry data will legitimately return nothing. What matters is a record that comes back **dissolved**, or one that comes back describing a different company than the one you thought you were buying from.
# Coverbase Screening
Source: https://docs.coverbase.com/products/coverbase-screening
Continuous sanctions, PEP, criminal, legal and adverse media screening for your vendors and the people behind them, with a recorded history of every screen.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase Screening checks whether a vendor, or a person who runs or owns it, appears on a sanctions list, a watchlist, a politically exposed person (PEP) register, a criminal or legal record, or in adverse news. It checks at intake, again on a schedule for as long as you keep the vendor, and whenever you ask.
Every screen is recorded, including the ones that find nothing. "We screened this vendor on this date against these sources and found nothing" is the record an examiner asks for, so Coverbase keeps it whether or not there is anything to review.
## What you can screen
| Subject | Screened by default | How it is identified |
| - | - | - |
| The vendor's legal entity | Yes | Legal name, headquarters country, and the registration number when [Corporate Registrations](/products/corporate-registrations) has one |
| Directors and officers | Opt in | Names from registry filings and [People Intelligence](/products/people-intelligence) research |
| Beneficial owners | Opt in | Names from registry filings |
| Anyone else, once | On demand | An **Ad hoc screen** of any organization or person, with or without a linked vendor |
People are opt in because screening a person means storing watchlist results about a named individual. Turn them on when your program needs them.
## What you can screen against
Screening covers five sources. Each is a separate lookup that you switch on or off for your whole organization.
| Source | What it covers | Default |
| - | - | - |
| **Sanctions** | Government sanctions and designation lists, including OFAC, the EU, UK HM Treasury, the UN and national lists. FATF high risk and increased monitoring jurisdictions are included. | On |
| **PEP** | Politically exposed persons, and their relatives and close associates, across national, regional and local government, state owned enterprises, diplomatic and security roles, and political parties | On |
| **Criminal** | Law enforcement and terror watchlists, and records of criminal charges | On |
| **Legal** | Civil and criminal litigation, lawsuits and judgments | On |
| **Adverse media** | Negative news about the subject, scored against the risk categories you choose, from over 200,000 outlets in more than 140 languages | Off |
The full catalog of lists, PEP roles and adverse media categories is in [Screening coverage and sources](/user-guides/screening-coverage).
## How it works
An administrator chooses which sources run and who is screened under **Configuration → Monitoring → Screening**.
Monitoring is switched on per risk level, so you can monitor your critical and high risk vendors continuously and leave the long tail to intake and on demand screens.
A monitored vendor is re-screened on a cadence set per source. By default that is daily for sanctions and monthly for PEP and adverse media. Each screen lands in the vendor's run history.
A possible match goes to the **Screening** queue and opens a finding with an owner and a due date. An analyst confirms it, marks it not a match, or allowlists it for 180 days. Coverbase never decides a match for you.
## Where screening runs
* **At intake.** The intake portal's pre-qualification step screens a requested vendor before anyone commits to it. See [Screen a vendor at intake](/user-guides/sanctions-screening#screen-a-vendor-at-intake).
* **On a schedule.** Monitored vendors are re-screened for as long as they stay monitored.
* **On demand.** **Screen now** on a vendor's **Screening** tab, and **Ad hoc screen** on the queue for a name you want checked once.
## Included, and configured on request
Most of screening is switched on from the settings page. Some options are set up by Coverbase for your workspace, and some carry an additional charge. Contact your Coverbase account team or [support@coverbase.ai](mailto:support@coverbase.ai) to change them.
| Option | How you get it |
| - | - |
| Sanctions, PEP, criminal and legal screening of the vendor entity | Settings page |
| Directors, officers and beneficial owners | Settings page |
| Adverse media, and the 12 standard risk categories | Settings page |
| Monitoring by risk level | Settings page |
| A different monitoring cadence for a risk level | Ask Coverbase to set up a profile group, then pick it in the settings |
| Adverse media categories beyond the standard 12 | Ask Coverbase |
| Your own internal watchlists and do not onboard lists | Ask Coverbase. Enterprise plans only. |
| Tuning match scoring, repeated alert suppression, and filtering of articles that only mention a similar name | Ask Coverbase |
Each monitored subject is a standing subscription, and every on demand screen is metered. Your account team can tell you what your plan includes.
## Get started
Every source, list, PEP role and adverse media category Coverbase screens against.
Reading a match, deciding it, and setting up the screening policy.
The other outside-in research on every vendor.
Where a new vendor is screened before it is onboarded.
# Detector library
Source: https://docs.coverbase.com/products/detector-library
Every out-of-the-box Supplier Radar detector template, organized by segment, with the default severity and what each one flags.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Supplier Radar ships with a library of ready-to-use detector templates. Each template becomes a live detector on your organization when you enable it from the dashboard (**New detector → From detector library** on the Radar page, or **Add detector** under **Configuration → Radar → Detectors**). It watches your sources for events that match its focus, enriches matches with vendor context, and routes them into triage. This page documents each built-in template so you can decide what to turn on.
The library currently includes **95 detector templates**. The dialog filters them by **Recommended** and by segment: **Cybersecurity**, **Financial**, **Operational**, **Legal**, **Compliance**, **Reputational**, **Contractual**, **ESG**, **Corporate**, **Geopolitical & External** and **AI Risk**. The **Corporate** segment lists no templates today. Most templates are *standard* detectors that read a natural-language goal and severity guidance. One is a *watchlist* detector that screens vendors against connected sanctions lists, and five are *Black Kite* detectors that read your Black Kite portfolio directly, with no AI step.
Detector templates are a starting point. Enabling a standard or watchlist template also adds the library sources it names to your organization and scopes the new detector to them, so it works without further setup; the preview in the dialog lists those sources. Once applied, every detector's instructions, severity threshold, category filters, sources, and reviewers are fully editable in the dashboard, and detectors learn from dismissed alerts. See [Supplier Radar](/products/supplier-radar) for the product overview and [Radar API](/api-reference/radar) for programmatic access.
## Severity levels
Each template ships with a default severity threshold. Detectors surface matches at or above their threshold; you can raise or lower it per detector.
| Severity | Meaning |
| - | - |
| High | Confirmed, material impact: active exploitation, confirmed breach, insolvency, sanctions |
| Medium | Credible, significant events warranting review |
| Low | Early or lower-impact signals worth monitoring |
| Informational | Contextual updates (for example, ownership changes) tracked without urgency |
## Recommended
The five templates every new organization starts with, already enabled. They also appear in their own segment in the dialog.
| Detector | Segment | Default severity | What it flags |
| - | - | - | - |
| Vendor Data Breach & Exposure | Cybersecurity | High | Confirmed or credibly suspected access to, exfiltration of, or exposure of vendor-held data, including breach notification filings |
| Ransomware & Destructive Attack | Cybersecurity | High | Ransomware, extortion, leak-site listings, and destructive attacks on vendors or their upstream providers |
| Exploited Vulnerabilities & Supply Chain Compromise | Cybersecurity | High | Actively exploited vulnerabilities, emergency patches, and software supply-chain compromises in vendor products |
| Operational Resiliency & Service Disruption | Operational | Medium | Outages, degradations, facility and disaster impacts, strikes, and continuity events |
| Vendor Financial Distress | Financial | Medium | Bankruptcy, going-concern doubt, credit downgrades, distressed funding, delisting, and severe earnings deterioration |
## Cybersecurity
Attack-surface, threat-intelligence, breach, privacy, and infrastructure-security signals affecting your vendors.
| Detector | Default severity | What it flags |
| - | - | - |
| Actively Exploited Vulnerabilities | High | CVEs, zero-days, and vendor product flaws exploited in the wild |
| Ransomware Vendor Impact | High | Ransomware and extortion incidents affecting vendors or service delivery |
| Malware or Supply Chain Compromise | High | Malicious packages, compromised updates, and supplier supply-chain attacks |
| Nation-State or APT Targeting | High | Nation-state or APT campaigns targeting a vendor, its products, or its sector |
| Confirmed Data Breach | High | Confirmed unauthorized access to vendor or customer data |
| Health Data and HIPAA Breach | High | Breaches of protected health information and HIPAA enforcement |
| Critical Patch Advisories | Medium | Emergency patches and critical security advisories |
| Cloud Service Security Incidents | Medium | Security incidents at cloud, SaaS, hosting, and identity providers |
| Credential or Token Compromise | Medium | Leaked credentials, API keys, tokens, and accounts in breach corpora |
| Identity and Access Control Failures | Medium | MFA bypass, account takeover, and IAM failures |
| Phishing and Social Engineering Campaigns | Medium | Campaigns abusing vendor brands, platforms, or employee access |
| Internet-Exposed Services and Misconfigurations | Medium | Exposed databases, admin panels, and risky misconfigurations |
| Malicious Infrastructure and Domain Reputation | Medium | Vendor domains or IPs reported malicious, blocklisted, or serving malware |
| Possible Data Exposure | Medium | Suspected leaks, exposed databases, and leak investigations |
| Privacy Regulatory Investigations | Medium | Privacy inquiries and regulator scrutiny of data practices |
| GDPR, CCPA, and Data Protection Actions | Medium | Fines and actions under major data-protection regimes |
| Third-Party Data Sharing Concerns | Medium | Risky vendor sharing, sale, or onward-processing of data |
| DDoS and Service Disruption Attacks | Medium | Denial-of-service attacks disrupting vendor platforms or customer access |
| Insider Threat and Data Theft | Medium | Rogue-employee data theft, insider fraud, and privileged-access abuse |
| Dark Web and Underground Exposure | Medium | Vendor data, access, or credentials advertised on criminal forums. Separate from [dark web monitoring](/user-guides/dark-web-monitoring), which watches leak sites and breach catalogs directly |
| ICS, OT, and IoT Vulnerabilities | Medium | Industrial, operational-technology, and connected-device flaws |
| Breach Notification Filings | Medium | Official breach notifications filed with regulators or attorneys general |
| Children's Data and Sensitive-Population Privacy | Medium | COPPA, minors' data, and sensitive-population privacy issues |
| TLS and Certificate Weaknesses | Low | Weak, expired, or mis-issued TLS certificates and transport-security gaps |
| Domain, DNS, and Email Security Gaps | Low | Subdomain-takeover risk and missing SPF, DKIM, or DMARC |
| Open-Source Dependency Risk | Low | Critical vulnerabilities or abandonment in open-source components |
### Black Kite templates
These five read your Black Kite portfolio against fixed thresholds and carry a **Black Kite** badge in the library. They can be enabled only once a Black Kite portfolio source is connected; see the [Black Kite monitoring guide](/user-guides/black-kite-monitoring).
| Detector | Default severity | What it flags |
| - | - | - |
| Exploited Vulnerabilities | High | A CISA KEV-listed vulnerability Black Kite found on a vendor's internet-facing infrastructure, with no susceptibility threshold |
| Critical Exploitable CVEs | High | Exploited vulnerabilities scoring CVSS 9.0 or higher with at least a 50% predicted chance of exploitation |
| Vulnerability Campaign Exposure | High | Black Kite focus tags naming a vendor as exposed to a campaign, such as a mass-exploited flaw or a ransomware wave |
| Ransomware-Susceptible Vendor Exposure | High | Exploited vulnerabilities and focus tags, only for vendors scoring above 0.5 on ransomware susceptibility |
| Highest Susceptibility Watch | High | The same signals, only for vendors scoring above 0.8 on ransomware susceptibility |
## Financial
Financial-stability, credit, financial-crime, and concentration signals.
| Detector | Default severity | What it flags |
| - | - | - |
| Bankruptcy or Insolvency Risk | High | Bankruptcy filings, insolvency warnings, and going-concern risk |
| Credit Rating Downgrades | Medium | Rating downgrades, covenant breaches, and debt-risk signals |
| Accounting or Internal Control Issues | Medium | Restatements, audit concerns, and control failures |
| Financial Crime Compliance | Medium | AML, KYC, sanctions, fraud, and market-abuse actions |
| Funding and Runway Risk | Medium | Down rounds, failed raises, and cash-runway warnings |
| Delisting and Exchange Warnings | Medium | Stock delisting notices, exchange warnings, and going-private distress |
| Adverse Media & Financial Crime | Medium | Fraud, money laundering, sanctions violations, corruption, and executive misconduct allegations |
| Financial Regulatory Enforcement & Supervisory Actions | Medium | Enforcement and supervisory actions by financial regulators such as the SEC, CFPB, OCC, FDIC, FINRA, and FinCEN |
| Fourth-Party & Concentration Risk | Medium | Incidents at shared subcontractors, subprocessors, and upstream providers, especially ones many vendors depend on |
| Earnings or Guidance Downgrade | Low | Material revenue, margin, or forecast deterioration |
| Insurance Coverage Risk | Low | Loss of cyber, liability, or required insurance coverage |
| Macroeconomic & Market Stress | Low | Credit-market, banking, currency, and rate shocks that could reach vendor viability or delivery |
| Concentration and Single-Source Risk | Informational | Signals that many customers depend on a single vendor or provider |
## Operational
Service, continuity, and corporate events that affect a vendor's ability to deliver.
| Detector | Default severity | What it flags |
| - | - | - |
| Service Outages and Degradation | Medium | Outages, degraded service, and major incident reports |
| Business Continuity Disruption | Medium | Events threatening a vendor's ability to operate or deliver |
| Product Recalls and Safety Issues | Medium | Recalls, safety alerts, quality failures, and hazardous products |
| Subprocessor and Fourth-Party Risk | Medium | Incidents at a vendor's critical subprocessors and fourth parties |
| Certification and Attestation Lapse | Medium | Expired, withdrawn, or failed SOC 2, ISO, and other certifications |
| Customer Support and Service Failures | Low | Widespread complaints about support, delivery, or service quality |
| Workforce Instability and Layoffs | Low | Mass layoffs and key-personnel departures signaling instability |
| M\&A and Change of Control | Informational | Acquisitions, divestitures, leadership shifts, and ownership changes |
## Legal
Enforcement, litigation, and conduct matters with material vendor impact.
| Detector | Default severity | What it flags |
| - | - | - |
| Government Contracting Suspension | High | Debarment, suspension, procurement bans, or contract termination |
| Regulatory Enforcement Actions | Medium | Formal enforcement, consent orders, penalties, and corrective actions |
| Material Lawsuits and Class Actions | Medium | Litigation affecting vendor stability, obligations, or reputation |
| Anti-Bribery and Corruption | Medium | Bribery, corruption, FCPA, sanctions evasion, and misconduct |
| Labor and Human Rights Actions | Medium | Forced labor, labor violations, and worker-rights disputes |
| Intellectual Property Infringement | Medium | Patent, copyright, or trade-secret suits threatening products |
| Data Localization and Sovereignty Actions | Medium | Data-residency, cross-border transfer, and sovereignty enforcement |
| Antitrust and Competition Actions | Low | Antitrust probes, competition rulings, and market-power enforcement |
## Compliance
Deterministic screening against connected sanctions and watchlist sources. It needs a watchlist source; enabling it adds the OFAC SDN list from the source library if you have none.
| Detector | Default severity | What it flags |
| - | - | - |
| Watchlist Screening | High | Screens monitored vendors against connected sanctions and watchlist sources |
## Reputational
Media, conduct, and trust signals that may warrant a vendor review.
| Detector | Default severity | What it flags |
| - | - | - |
| Executive Misconduct | Medium | Misconduct, resignations, investigations, and governance concerns |
| Whistleblower Allegations | Medium | Credible whistleblower disclosures of misconduct or safety failures |
| Negative Media Spikes | Low | Sudden negative coverage that may require review |
| Major Customer Losses | Low | Loss of key customers, partnerships, or market trust |
| Misinformation or Harmful Content | Low | Content-moderation, platform-abuse, and harmful-use issues |
| Security Reputation Drop | Low | Public downgrades or negative analyst reports on security posture |
| Social Backlash and Boycott | Low | Viral backlash, boycotts, and coordinated reputation campaigns |
| Greenwashing and ESG Misrepresentation | Low | Misleading sustainability, diversity, or ESG claims |
## Contractual
Contract performance signals.
| Detector | Default severity | What it flags |
| - | - | - |
| Contractual SLA Penalties | Medium | Penalties, contract breaches, and SLA failures |
## ESG
Environmental enforcement and sustainability signals.
| Detector | Default severity | What it flags |
| - | - | - |
| Environmental Enforcement | Medium | Environmental fines, pollution incidents, and permit violations |
## Geopolitical & External
Sanctions, export controls, geopolitical events and natural hazards touching vendors or their regions.
| Detector | Default severity | What it flags |
| - | - | - |
| Geopolitical & Sanctions Exposure | High | Sanctions designations, export controls, conflict, and instability touching vendors or their operating regions |
| Geopolitical or Sanctions Disruption | Medium | Geopolitical exposure, sanctions, export controls, or instability |
| Natural Hazard Near a Supplier Site | Medium | Earthquakes, storms, floods, wildfires and severe weather reaching the location of a vendor's site. See the [natural hazard monitoring guide](/user-guides/natural-hazard-monitoring) |
## AI Risk
AI- and model-specific incidents, security, governance, and regulatory signals, for vendors that build or depend on AI systems.
| Detector | Default severity | What it flags |
| - | - | - |
| AI Security: Jailbreaks and Prompt Injection | High | Jailbreaks, prompt injection, and adversarial exploitation of vendor AI |
| AI Data Leakage and Training-Data Extraction | High | Sensitive-data leakage via AI systems, memorization, or training-data extraction |
| AI Model Supply-Chain and Provenance | High | Poisoned models, malicious artifacts, and compromised model-hub supply chains |
| AI Security & Data Leakage Incidents | High | Exploited jailbreaks and prompt injection, data leakage, poisoned models, and compromised AI supply chains |
| Biometric and AI Privacy Risk | Medium | Privacy issues tied to biometrics, AI systems, and automated decisions |
| AI Model Safety Incidents | Medium | Unsafe, harmful, or out-of-scope AI outputs and model-behavior incidents |
| AI Training-Data and IP Disputes | Medium | Copyright, licensing, and IP litigation over training data and outputs |
| AI Regulatory Enforcement | Medium | EU AI Act and other AI-specific regulatory action and enforcement |
| AI Bias and Discrimination | Medium | Algorithmic bias, discriminatory outcomes, and automated-decision harm |
| AI Model Outage & Deprecation | Medium | AI/LLM API outages, model deprecations, and capability changes |
| AI Deepfake and Brand Impersonation | Medium | Deepfakes and synthetic media impersonating a vendor or its executives |
| AI Legal, Regulatory & IP Actions | Medium | AI-law enforcement, training-data IP litigation, bias claims, and biometric and AI privacy actions |
| AI Safety, Deepfake & Misuse Incidents | Medium | Harmful AI outputs in vendor products and deepfake abuse of a vendor's brand, executives, or platform |
| AI Governance and Transparency Gaps | Low | Responsible-AI program failures, missing disclosures, and governance lapses |
| Shadow AI and Unsanctioned Use | Low | Unsanctioned AI-tool use that may expose customer or regulated data |
| Vendor AI Adoption & Data-Use Changes | Low | New AI features, changed AI data-use or training practices, new AI subprocessors, and undisclosed AI use |
## Related
The companion library of built-in source templates that these detectors read from.
The product overview: signal ingestion, enrichment, triage, and workflow orchestration.
Create radar events, and list, retrieve, and dismiss radar alerts programmatically.
The companion library of built-in control-set templates, including AI governance frameworks.
Subscribe to `RadarDetectorResult.*` events and react in real time.
# Document Insights
Source: https://docs.coverbase.com/products/document-insights
Org-defined fields extracted from every document, with a verbatim source quote, page citation, and confidence on each value.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Document Insights turns any document your organization collects into structured, queryable data. You define the fields once (an effective date, a liability cap, a breach-notification window, an audit period), and Coverbase populates them automatically whenever a matching document is processed. Every value carries a verbatim source quote, a page citation, and a confidence level, so a reviewer can verify it without opening the file.
Insights are the field-level layer of contract intelligence. [Contract Guardian](/products/contract-guardian) is the language-level layer, comparing vendor clause language against your playbook. They run over the same documents and feed the same records.
## What it does
You decide what gets extracted. Each insight has a name, a description that instructs the model, a value type (text, number, date, yes/no), and a mode. No fixed schema to work around.
Every value is checked against the document. The supporting quote must appear in the source as a contiguous span, and the cited page is corrected to where the quote lives. An answer whose quote cannot be located is kept but marked unverified, and waits for a reviewer to accept it.
Insights apply to the document types you choose, individually or through groups that share scope. A liability-cap field runs on MSAs, not on SOC 2 reports.
**Extract** returns one concise, typed answer: a name, a date, a number, or Yes/No. **Synthesize** writes a short summary for a Text insight. Both cite the language that supports the answer.
## Extract vs Synthesize
The mode determines the shape of the answer: a single typed value, or a written summary.
| Mode | Behavior | Use it for |
| - | - | - |
| **Extract** | One concise answer in the insight's type. The model prefers the document's wording and interprets only as far as the type needs, so a Yes/No insight reads the clause and answers Yes or No. It must cite a verbatim quote, which Coverbase checks. Returns empty when the document can't answer. | Dates, party names, jurisdictions, figures, named frameworks, yes/no judgments: anything you want as one value to sort and filter on |
| **Synthesize** | The model writes a short summary that combines or explains what the document says, and must cite a verbatim quote supporting it. Available for Text insights only. Returns empty when the document can't answer. | Rollups across sections, plain-language verdicts, the gist of terms every counterparty words differently |
**Yes/No**, **Number** and **Date** insights always use Extract, because Synthesize only takes Text. A Yes/No, Number or Date insight created earlier with Synthesize now runs as Extract and needs no change.
The [Document Insights guide](/user-guides/document-insights) covers mode selection in depth, along with a starter library of insight definitions to copy.
## What each value carries
| Field | Description |
| - | - |
| Value | Stored in its declared type. Dates normalize to ISO `YYYY-MM-DD`; numbers strip currency symbols and separators |
| Source quote | The exact span from the document supporting the value, verified to exist in the source |
| Page number | 1-indexed physical page containing the quote |
| Confidence | `high` when explicitly stated, `medium` when inferred, `low` when uncertain |
| Reasoning | Notes on ambiguities or assumptions made during extraction |
| Source type | `ai_extracted` or `manual`, so hand-corrected values are always distinguishable |
## How it runs
When a document finishes processing, every enabled insight matching its type is extracted in the same pass. Insights grouped by mode run as separate calls.
Re-extract a whole document or a single insight after you add or reword a definition.
A new definition starts empty on documents already processed. A backfill re-extracts them in bulk, scoped by insight, document type, or vendor, with a cost estimate before it runs.
PDFs are read natively, including their layout. Long documents are chunked with page overlap and results merged, preserving original page numbering. Excel workbooks are grounded per worksheet.
Insights roll up onto the contract record, feed the contract AI summary, and export to CSV with every value, citation, and confidence intact.
## Auditing coverage
Defining insights is the easy half. Knowing whether they *worked* is the half that decides if anyone trusts the data.
**Configuration → Document Insights** is the module for that. It shows the same set of extractions through three lenses:
| Lens | Answers |
| - | - |
| **Insights** | What have we defined, and is each definition healthy? |
| **Document types** | Is this document type well covered? A matrix of document type against insight, with a fill rate in every cell |
| **Extractions** | Is this specific value right? Every extraction in the org, filterable by confidence, groundedness, and source |
### The number that matters
A blank cell in the coverage matrix means one of two opposite things, and the module keeps them apart:
Extraction ran and found nothing. Either the definition is ambiguous, or the term genuinely isn't in that document. This is a **prompt problem**. Open the Extractions tab and read what it returned.
The insight was created after the document was last processed, so it has never run against it. This is a **backlog problem**; one backfill fixes it. The matrix marks these as *stale*, and the badge is the button.
## Promoting insights into custom fields
An extraction lives on a document. A custom field lives on the record people work from: the vendor, the contract, the assessment. Promotion connects them.
Link an insight to a custom field and Coverbase fills that field from the extraction whenever a matching document is processed, then backfills the field across every document you already hold. The field keeps a pointer to the document, page, and verbatim quote it came from, so a value on a contract record can show you *why* it holds that value.
| Insight type | Fills a custom field of type |
| - | - |
| Text | Text |
| Number | Number |
| Date | Date |
| Yes/No | True/False |
Select and multi-select fields are not promotable yet. Mapping free text onto a fixed option list needs the options fed into the prompt, not matched after the fact.
Two gates decide what gets promoted, and one rule is absolute:
* **Require a grounded quote** (on by default) skips any answer whose supporting quote could not be located in the source.
* **Minimum confidence** skips answers below the bar you set.
* **A value a person typed is never overwritten.** Not by a backfill, not by a later upload, not by any conflict policy. Automated writes only ever replace other automated writes.
## Common workflows
Define the fifteen fields your team asks of every agreement (value, effective date, term, renewal, notice period, liability cap, governing law, data return, audit rights) and get them populated on every contract as it lands, instead of maintaining a spreadsheet by hand.
Extract audit periods, report scopes, certification expiry dates, and auditor names from SOC 2s and ISO certificates so evidence freshness can be tracked without a human reading each report.
Once a field exists on every contract, portfolio-wide questions become answerable: which agreements auto-renew inside 60 days, which permit customer data in model training, which cap vendor liability below one year's fees.
An answer whose quote could not be verified is flagged for review, and a reviewer can accept it with the evidence still marked unverified. A value set through the API is marked as manual with the user recorded, and automated writes never overwrite it.
Insight values surface on the document, on the contract record, in the contract AI summary, on any custom field you promote them to, and through the [MCP server](/mcp/overview) for natural-language querying.
# Document library
Source: https://docs.coverbase.com/products/document-library
The library of vendor documentation Coverbase collects and curates itself: where the documents come from, how they are reviewed, and why nothing you upload ever ends up in it.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Open the **Documents** tab on almost any vendor and you'll find a section called **Coverbase library documents** that is already populated. A SOC 2 report, an ISO certificate, a pen test summary. Nobody on your team put them there, and people reasonably want to know two things: where these came from, and whether their own documents are sitting in someone else's account the same way.
## What the library is
The document library is vendor documentation that **Coverbase collects and curates itself**, so a vendor's evidence is often waiting for you before you've asked anyone for it. It's keyed to the company rather than to your organization. Coverbase resolves each vendor record to a canonical company, and every customer assessing that same company sees the same library.
Our agent requests documentation from the vendor and retrieves what they publish, on our own initiative.
Nothing reaches the library until a Coverbase reviewer has approved it.
Documents you or your vendors upload to Coverbase are never added to the library.
## Where the documents come from
There are two routes, both run by Coverbase and neither triggered by a customer asking for anything.
* **We ask the vendor.** Our agent requests documentation from the company directly, on Coverbase's own behalf. This is how the library gets hold of material that isn't published anywhere.
* **We retrieve what the vendor publishes.** Trust centers (Drata, Vanta, SafeBase, custom portals), certification registries, and official disclosures. Anything ungated is downloaded, and for gated material the agent completes the access request.
What we don't do is scrape the open web for anything that looks like a vendor document. Material harvested that way is usually stale, often the wrong version, and sometimes not the vendor's document at all. A library full of that is worse than an empty one, because it still looks authoritative sitting in an audit file. Three current documents beat thirty scraped ones.
This is separate from how an assessment researches the public web while evaluating a control. That path has its own accountability filter and is documented in [Evidence quality and source credibility](/user-guides/evidence-quality).
## What never goes into the library
**Your documents stay yours.** Nothing your organization uploads to Coverbase is ever added to the document library, and nothing a vendor sends you through an assessment portal is either. There is no path, manual or automated, that promotes a customer-owned document into the shared library.
This isn't only a policy. It's how the system is built:
* Only Coverbase staff can add a document to the library. The write path is closed to customer organizations completely, so a document can't land there from your side even by accident.
* Everything in the library was obtained by Coverbase on our own initiative, not in response to any customer's request or upload.
* Your own vendor documents live in a separate, org-scoped store, under the tenant isolation described in [Data protection](/security/data-protection). They appear on your vendor's Documents tab in their own section, above the library.
The two sections on that tab come from completely different places. The upper one is yours and private to you. The lower one is ours and shared.
## How documents are curated
The agent requests or retrieves the document and files it against the company.
Each document is given a type (SOC 2 Type II, ISO 27001 certificate, pen test report, and so on), a publication date, and an expiry date.
A Coverbase reviewer checks the document before it is approved. Until then it isn't visible to anyone outside Coverbase.
Expiry follows the document type, not a single global rule: attestations and pen tests age out faster than company policies. Expired documents are hidden by default, with a **Show expired** toggle when you want to see them anyway.
## Where you'll see it
The card carries a short explanation of its own. Click the question mark next to the heading for the same answer this page gives, without leaving the vendor.
The **Documents** tab shows **Coverbase library documents** below your organization's own documents. **Import** on a row copies that document into your organization's own documents; a file you already hold is skipped.
**Import from Coverbase Library** is one of the five evidence-collection routes, showing the count available before you click. See [How to run an assessment](/user-guides/running-an-assessment#part-3-collect-the-evidence).
When you import a library document into an assessment, or with **Import** on the vendor's **Documents** tab, Coverbase copies the file into your organization and attaches the copy as a vendor document. Duplicates are skipped, so the same file is not attached twice.
## Frequently asked questions
No. Customer-uploaded documents are org-scoped and are never promoted into the library. Only Coverbase staff can add library documents, and every one of them was obtained by Coverbase independently.
Because the library is built ahead of demand. Coverbase collects documentation for companies across its coverage, so a well-known vendor often has substantial evidence waiting before anyone assesses them. It doesn't mean someone in your organization requested it.
For most evidence, yes. It's the vendor's own document, retrieved from the vendor or their trust center and reviewed before publishing. Check the publication and expiry dates the way you would for any document, and go to the vendor directly when you need something scoped to your specific engagement.
Tell us at [support@coverbase.ai](mailto:support@coverbase.ai). Corrections apply at the library level, so a fix reaches everyone assessing that company rather than only your organization.
## Related
The full walkthrough, including all five evidence-collection routes on the Documents tab.
How web evidence is graded for publisher accountability before it can be cited in an assessment.
The browser-based inspection that reads vendor trust centers and converts attestations into verified evidence.
Encryption, tenant isolation, retention, and deletion for the data your organization owns.
# Due diligence
Source: https://docs.coverbase.com/products/due-diligence
How each Risk Group gathers evidence and works with the vendor: assessment methods and review sessions, question delegation in the portal, answers carried forward from last time, reviewer edits the vendor approves, service-level questionnaires, findings raised on a question, and the acceptance chain for risk.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Due diligence is the work your Risk Groups do on an assessment: collecting the vendor's answers and evidence, meeting the vendor where a questionnaire is not enough, and deciding what to do about each finding. These capabilities sit on top of [Assessment Copilot](/products/assessment-copilot) and the [supplier portal](/user-guides/centralized-supplier-portal). They change how evidence is gathered and who signs off on risk, not how controls are evaluated.
Your Coverbase representative turns on the third-party lifecycle features for your organization.
## What it does
Each assessment records how evidence is gathered: **Questionnaire**, **Remote review** or **Onsite**. Remote and onsite reviews schedule review sessions with a time, a place or link, internal participants and vendor attendees, who are notified when a session is scheduled, changed or cancelled.
A supplier can hand a section, or individual questions, to a colleague. A question assignment wins over its section's, which wins over the whole form's, and the portal shows who answered what.
When the same questionnaire goes to a vendor again, their previous answers are copied in. The vendor confirms each one or changes it, and cannot submit until every carried-forward answer is confirmed or updated. Reviewers see which answers changed.
When a reviewer edits a vendor's answer, the vendor sees the before and after in the portal and either approves the edit or suggests different wording.
Questions can be marked service-level. When a vendor's company-wide due diligence is current, a new service can be sent only those questions instead of the whole questionnaire.
A finding records what it was raised on: a question, a risk domain, a questionnaire, an assessment, a service or the vendor. A reviewer can raise one directly on a question from the vendor's answer.
## The acceptance chain
Accepting a finding's risk can be routed through a chain of people instead of one approver. Rules under **Findings Settings** match a finding by its severity or risk level, first match wins, and name:
1. The **finding owner**, who proposes to accept the risk, have the vendor remediate, or escalate.
2. An optional **recommending group**, typically the Risk Group for the domain, which recommends.
3. A **deciding group**, typically the TPRM Office, which decides and may decide at any point, overruling what came before. The overrule is recorded as one.
4. An optional **extended approver**, who must also approve an acceptance that runs longer than the rule's number of days.
An acceptance always has an end date, at most 366 days out. Once a finding is routed, every way of moving it to risk accepted, from the finding page, a bulk action, an import, a workflow or the API, is refused until its chain has approved the acceptance, and the exception it creates cannot outlast the end date the chain approved. A finding that no rule matches follows the single-approver path. See [The issue acceptance chain](/user-guides/issue-acceptance-chain).
## When the vendor's due diligence is current
The abbreviated, service-level send is offered only when the vendor has a completed assessment and its next assessment date has not passed. Otherwise the option is disabled and explains why.
## What it does not do
* Carried-forward answers are matched by question across questionnaire versions. A question added since the last submission starts empty, and nothing the respondent has already answered on the new request is overwritten.
* An onsite review does not upload evidence for you. Reviewers upload what they collected and record control effectiveness by hand from the assessment.
* The acceptance chain does not change who may raise or close a finding. It governs accepting risk only.
## Checking answers against evidence
[Claim check](/products/claim-check) tests each answer on a submission against the vendor's SOC reports, certifications, trust center documents, outside-in scan, licensed ratings and contract terms, marks it **Supported**, **Contradicted**, **Needs evidence** or **Not covered** with the cited passages, and lets the reviewer raise a finding or ask the vendor to clarify from the result.
## Where to go next
Methods, sessions, delegation, carry-forward, edit approval and service-level sends, step by step.
Set up routing rules and record proposals, recommendations and decisions.
How completed domain reviews add up to a Risk Summary for the Transaction Owner.
Statuses, commitments and remediation once a finding exists.
# Engagement record and Risk Summary
Source: https://docs.coverbase.com/products/engagement-record
The engagement as the Transaction Owner sees it: where the request is, each Risk Group's review, the due diligence that counts toward it, and the Risk Summary they decide on.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
An engagement is one piece of business with a vendor: the service a Transaction Owner is buying. The engagement record puts everything that happens to that piece of business on one page, so the person who asked for it can see where it is without asking the TPRM Office, and the TPRM Office can see which Risk Groups are still working.
Your Coverbase representative turns on the third-party lifecycle features for your organization.
## What it does
**Where This Request Is** shows the stage (Request, Triage, Inherent risk, Due diligence, Decision, Contract, Active, Exit) and an expected decision date. Everyone involved in the engagement sees the same tracker.
Each risk domain that needs a review shows its status: Complete, Reused, In review, Waiting on vendor or Not started, with the reviewer.
Assessments are linked to the engagement. A linked assessment performed for something else can be marked as reused, and a Front Door reuse decision links the prior assessment automatically.
Per domain: inherent risk, control effectiveness and residual risk, read live from the linked assessments. The TPRM Office adds a recommendation and conditions, the Transaction Owner records the decision, and the summary downloads as a PDF.
The Transaction Owner and the TPRM Office are told when due diligence goes out to the vendor and when it completes. The Transaction Owner receives the Risk Summary automatically when the last Risk Group signs off.
Set a vendor's parent company to see the family's rating, contract value and engagements rolled up to the ultimate parent.
## When due diligence is complete
A risk domain needs a review on a linked assessment by the same rule the assessment's own review progress uses. A domain is **complete** when every performed assessment that needs it has finished its review of it, and **reused** when a reused assessment has. Due diligence is complete when every domain is one or the other. Archived and canceled assessments drop out.
A Front Door reuse decision satisfies exactly the domains it marked for reuse, and nothing it marked for an abbreviated review or new due diligence.
## The Exit stage
Exit is the eighth stage, after Active. An engagement reaches it when someone files an offboarding request for it that is not canceled or archived.
* While the request is requested or in progress, Exit is the current stage and reads **Exit under way**. Every earlier stage shows as done, and the header badge reads **Exiting**.
* Once the offboarding completes, Exit shows as done with **Exited** and the date, and the header badge reads **Exited**.
* A live engagement with no exit planned keeps Active in focus, reading **Live since** and the date the contract went live, with Exit upcoming.
Program Insights counts an exiting engagement as active until its exit completes. An exited engagement leaves the program's figures. The engagement list's **Stage** filter includes **Exiting** and **Exited**.
## The expected decision date
The expected decision date is when the last open domain review's SLA runs out. A review already running uses its remaining time; one not started uses its full target, counted from when the vendor's open request is due, or from today. Business days follow the SLA clock. If any open review has no SLA target, no date is shown, and none is shown once a decision is recorded.
## The decision
Only the Transaction Owner, or someone who can update the vendor, records the decision, and only once due diligence is complete. **Proceed to contracting** opens the contract handoff for Supply Chain, unless one is already pending or done. **Don't proceed** records the decision and stops there.
The Transaction Owner is the engagement's relationship owners (people and groups) plus whoever raised the intake request a linked assessment came from. An engagement with no owners of its own falls back to the vendor's.
## Delivery tracking
The **Delivery** card on the Risk Summary shows, for each recipient, whether the summary is **Sent**, **In their notifications**, **Seen** or **Read in app** in Coverbase, and when it was emailed.
Email open tracking is off by default. An admin can turn on **Risk Summary Open Tracking** under **Configuration → Communications → Lifecycle Routing and Reminders**. With it on, the Risk Summary email, and no other email, carries a tracking pixel, and the card shows **Email opened** with the date of the first open, or **Email not opened yet**.
* Only the first open is kept. The recipient's mail client, operating system, IP address and location are discarded and never stored.
* An open is an image load. A mail client that blocks images never reports one, and a security scanner that fetches images can report one before anyone read the email. Treat an open as a signal; **Read in app** is the stronger fact.
* A summary sent to someone on a digest arrives inside a grouped email, which is never tracked.
* Turning tracking off stops it at once. Opens already recorded keep showing.
## Where to go next
Link diligence, read the tracker, write the recommendation and record the decision.
Where reuse decisions are made.
What the engagement owes once it is active.
The contract handoff, continuity plans and the exit.
# Financial Health Score
Source: https://docs.coverbase.com/products/financial-health-score
A 0-100 view of whether a vendor is financially sound enough to depend on, computed from filed statements where they exist and from signals where they do not, always labelled with which.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Coverbase Financial Health Score answers one question about a vendor without asking the vendor anything: **is this company financially sound enough to depend on?** It runs 0-100, where higher is healthier, and it is computed from regulatory filings where a company files them and from funding, headcount, and corporate-standing signals where it does not.
What makes it usable in practice is how it's acquired: no supplier outreach, no questionnaire, no waiting on a vendor to opt in. Coverage is portfolio-wide from day one, and every vendor is rescored on each Vendor Intelligence run.
This is an optional feature. Ask your Coverbase representative to turn it on for your organization.
## What it does
Every score is published with the confidence tier behind it, so an inferred number is never presented with the authority of an audited one. The tier is derived from what resolved, never declared.
A ratio only means something against a comparable set. Coverbase ranks each vendor inside its own industry cohort, drawn from thousands of filers that reported the same concept in the same period.
Open the rationale on any pillar and you get the inputs behind it: each one's measured value, what it scored, how heavily it counted, and whether it was ranked against peers.
A bankruptcy filing or a dissolved registration doesn't get averaged into a weighted mean. It pins the score, and the card says which rule fired.
## Confidence tiers
**This is the most important thing on the card.** A Tier C 72 and a Tier A 72 are different claims about different evidence. The tier travels with the score everywhere the score goes: into the API, into MCP answers, into exports.
| Tier | Backing data | What you get |
| - | - | - |
| **A: Filed financials** | Financial statements the company filed with a regulator (SEC EDGAR XBRL), or statements you submitted yourself | The full ratio battery, ranked against peers. Statement-grade. |
| **B: Estimated financials** | Estimated revenue and EBITDA plus capital structure, where your organization has an estimates provider enabled | Partial ratios computed on estimates, full capital position and momentum |
| **C: Signals only** | Funding, headcount, corporate standing, and adverse events | Capital position, momentum, standing, and events. No financial statements were available. |
If a vendor's filings stop resolving, it drops to a lower tier and the card says so. It does not keep presenting a statement-grade number built on estimates.
Scores are held to a common scale across tiers by the stability class below, so ranking a mixed portfolio on the raw number is reasonable. The tier still tells you how much evidence stands behind any individual result, and it belongs in any conversation about a surprising one.
## Stability classes
A single number cannot order companies that survive by different mechanisms. An entrenched, cash-generative incumbent and a venture-funded startup are not two points on one axis, and treating them as one produces a ranking that is hard to defend in front of a customer.
Every vendor is therefore assigned a **stability class**, derived from observable scale, operating history, cash generation and dependence on outside capital. Never from a name, a ticker, or an opinion.
| Class | Roughly |
| - | - |
| **Entrenched incumbent** | Files audited statements, very large, long-established, generates cash |
| **Established operator** | Real revenue or headcount, years of history, covers its own costs |
| **Funded scale-up** | Past the fragility of a small team, still funded rather than self-sustaining |
| **Early-stage, capital-dependent** | Small or young, dependent on the next raise |
| **Distress signals present** | Insolvency, closure, or cash running out |
Each class occupies a score range, and the ranges are ordered so an early-stage company's ceiling never reaches an established company's floor. A vendor that recently raised cannot out-rank a profitable incumbent on inference alone.
Two limits on that. **Evidence outranks inference:** the ranges constrain what may be inferred, and a bankruptcy filing or going-concern opinion drives a score straight through any floor. And **every adjustment is published.** Where a floor or ceiling moved a score, the card shows the rule, the reason, and the before-and-after figures, so a corrected number does not read as a computed one.
## Runway and burn for private companies
For the majority of a portfolio that files nothing, the score models how long the company's cash lasts.
Burn is derived from headcount rather than guessed. Fully-loaded cost per employee is the operating figure that behaves most predictably across software companies, adjusted for stage and grossed up from personnel to total operating cost. Revenue is netted off at gross margin, using a conservative stage estimate where no figure is available. Capital is the last round plus a reserve, less what has been consumed since.
The output is a **range**, along with two readings that often matter more than the midpoint: whether the company is **self-sustaining** (revenue covers burn, so no cliff applies), and its **capital efficiency** (revenue per dollar raised). Every assumption used is recorded on the scorecard.
Most private rounds are reported with a size but no closing date. Crediting the vendor with a round closed yesterday flatters it, and charging a fixed number of months of burn penalises the companies with a large payroll. So an undated round is treated as half spent: observing a company at an unknown point in its funding cycle is observing it, on average, halfway through.
These are bounded estimates, labelled as such. They separate a vendor with two years of cover from one with two quarters, which is the distinction that affects a buyer. They are not a guess at a bank balance.
## Funding and headcount without a data subscription
The model above needs a headcount and, ideally, a last round. Crunchbase and PitchBook supply both, for the customers who license them and for the vendors those providers happen to cover.
Coverbase's own enrichment also researches each vendor's employee count, last round size, round type and founding year from public sources, and the score reads those directly. For a portfolio with no financial-data subscription behind it, that is the difference between a cash model that runs and one that never had a headcount to price.
Two rules apply. Researched figures are cited as **Web research** rather than attributed to a provider Coverbase never called, and they never raise a vendor's confidence tier, because a search result is not a filing however precise it looks. Where a licensed provider does answer, its figure wins and the researched one fills gaps only.
## What the score is built from
Five pillars. Which ones carry the score depends on the tier, because a tier with no filed statements has nothing to put in the financial core:
| Pillar | Tier A | Tier B | Tier C | What it covers |
| - | -: | -: | -: | - |
| Financial core | 50% | 30% | n/a | Margin, liquidity, leverage, coverage, and cash generation from filed statements |
| Capital position | 15% | 30% | 40% | Runway, debt maturity proximity, time since last raise, down-round history |
| Momentum | 15% | 20% | 30% | Direction of travel: revenue growth, headcount trend, funding cadence |
| Adverse events | 15% | 15% | 20% | Distress events weighted by severity, decayed by age |
| Corporate standing | 5% | 5% | 10% | Registration status, jurisdiction, filing compliance |
The weights renormalize over the pillars that exist for a vendor, which is why a Tier C score is not a Tier A score with holes in it.
## How a score is computed
A single outlier filer shouldn't set the top or bottom of the scale for everyone else.
This is the step that does the real work, and it matters more than any weight. It's what makes 4x debt/EBITDA at a utility and at a software company comparable. Ratios where lower is better (leverage, days sales outstanding, burn) are inverted so that higher always means healthier.
Where the trend matters as much as the level, the input score is weighted toward the current level but carries a meaningful share of the direction it's moving.
The events pillar doesn't percentile-rank. It sums decayed severity, so a two-year-old event does not weigh the same as last month's. Positive events carry negative severity and pull the burden back toward zero.
Each pillar is a weighted mean over the features present; the composite is a tier-weighted mean over the pillars present.
Damps routine churn so the score doesn't jitter on noise.
A model grades the vendor's resilience from the same evidence the card lists, and nothing else. Its grade carries 20% of the score at Tier A, 35% at Tier B and 50% at Tier C, less when the model is unsure, and it can never move the score by more than 20 points. If the grade fails, the arithmetic stands on its own.
The guardrails described under [stability classes](#stability-classes) apply to the blended score, so a model grade cannot lift a vendor out of its class either.
An override is not averaged in. See [caps and floors](#caps-and-floors) below.
0-19 Very High Risk · 20-39 High · 40-59 Medium · 60-79 Low · 80-100 Very Low.
### Two rules that shape everything
Missing features drop out and the remaining weights renormalize. The cost of sparse data is paid by the **confidence tier**, not by the score. Otherwise a poorly-covered vendor would look distressed purely for being poorly covered, which is a very expensive kind of wrong.
The same applies at the ratio level: a ratio with a zero, missing, or wrong-signed denominator is treated as *absent*, not as zero.
The rule above says sparse data must not read as distress. It does not license sparse data reading as strength.
An *observation we never made* is capped rather than scored perfectly. For a company whose filings we read, an empty adverse-event stream really does mean nothing was disclosed; for a private company it means nothing was observed, and it is scored well but not perfectly. Likewise a score resting on neither statements nor a defensible cash estimate is held below the top band.
Read together, the two rules are what keep the least visible vendors in a portfolio out of the top of the ranking.
Smoothing damps routine movement in both directions, but severe events and every override bypass it entirely. A company recovering from distress climbs gradually as the evidence accumulates; a company entering distress drops immediately.
## Peer comparison
A ratio in isolation is not a judgement. 4x debt/EBITDA is unremarkable at a utility and alarming at a software company, so every Tier A ratio is scored as a percentile inside a cohort rather than against an absolute threshold.
**The cohort is real, and it is large.** It's built from the population of filers that reported the same concept in the same period: typically thousands of companies per ratio, not a hand-picked comparison set.
**Industry narrows it.** Ranking a software vendor against every filer (banks, REITs, miners) produces a percentile that is arithmetically correct and analytically meaningless, so cohorts are scoped to the vendor's own industry classification.
**When the cohort is too small, the card says so.** The score falls back to a wider population and discloses that it did. A disclosed wide cohort is honest; an undisclosed one is misleading.
Tier B and C signal features (funding, headcount) are scored against documented absolute curves rather than peer percentiles, because no equivalent free population exists for them. Any input scored that way is flagged as not peer-ranked, both on the card and in the API.
## Caps and floors
Some facts should not be averaged. A bankruptcy filing is not a modest deduction to be offset by a healthy current ratio, so these rules apply after the weighted score and override it outright:
| When | Effect |
| - | - |
| Registration dissolved or in liquidation, or a bankruptcy filing | Score pinned at 5 |
| Going-concern doubt in an audit opinion | Capped at 30 |
| Operating status reported as closed | Capped at 15, pending review |
| Debt maturing within 12 months **and** either negative free cash flow or more than 30 months since the last raise | Capped at 45 |
Every override that fires is recorded with its reason and shown on the card, so a pinned score explains itself rather than looking like an unusually harsh weighted result.
## Adverse events
Events that bear on financial health (bankruptcy filings, going-concern doubt, mass layoffs, auditor changes, delistings, CFO departures, down rounds, material impairments, regulatory actions, late filings) are weighted by severity and decay over time.
Events awaiting human confirmation are labelled **Needs review**, and they do not move the score until they are confirmed. Dismissed events stay on the record for audit but stop affecting the number.
## What the card shows
* **A one-to-two line summary** covering what the score was built on, the stability class, and how much runway the company has
* **Score, risk band, and confidence tier**, with 3-month and 12-month movement
* **Pillar breakdown**, each with the weight it carried and the inputs behind it
* **Financial vitals**: revenue and growth, operating margin, current ratio, debt/EBITDA, interest coverage, free cash flow margin, estimated runway, total raised, headcount, last funding round
* **Registered entity standing**: status, jurisdiction, and filing compliance
* **Peer context**: the cohort the vendor was ranked inside and its percentile within it, with any fallback disclosed
* **Score history**, plotted as discrete restatements rather than a smooth line, because each point is a separate computation
* **Adverse events** with date, review status, and a link to the source that reported each one
* **Caps and floors** applied, with the reason
* **Sources**, each with the date its data was true, plus the sources that were asked for and unavailable
### Why this score?
Open the rationale on any pillar and the card shows the inputs that produced it, each with the measured value, what it scored, and how heavily it counted. Inputs are ordered by how much they cost the pillar, so the reason for a low score is at the top.
A capital position of 50 might resolve to a current ratio of 1.8x scoring 62 at half the weight, and a registration status Coverbase could not determine. That second one matters more than it looks: an undeterminable input is labelled as such rather than shown as a bare number, because "50" reads as measured mediocrity when it means nobody knows.
Two things travel with every input:
* **Whether it was peer-ranked.** An input scored against the vendor's own cohort is a much stronger claim than one scored against an absolute curve.
* **The date the value was true.** Filed figures lag. An input from a filing two quarters old carries its own as-of date, not the date of the refresh.
## Submitting a vendor's own financial statements
Most vendors are private companies, so most score Tier C however sound they are: there is nothing filed to read. If you already hold that vendor's financials -- and in a diligence relationship you usually do -- you can give them to Coverbase and the score is rebuilt on them.
**Vendor Intelligence > Financial**. **Upload financial statements** sits in the page header, between **Refresh** and **Export**. **Upload supporting information** in the actions menu (**...**) opens the same dialog. When the window is too narrow, **Upload financial statements** moves into that menu too.
Audited financials, tax returns, SEC filings, management accounts. Supporting evidence belongs here too -- a Dun & Bradstreet report, a Better Business Bureau profile, a consumer report. Coverbase reads those for the entity's identity and for concerns, and will not invent fiscal periods from them. **Link existing documents** adds files already on the vendor's Documents tab without uploading them again.
**Generate analysis** runs it. Uploading and generating are separate on purpose -- you can add files across several sessions and run the analysis when the set is complete. One pass reads every document together, because a statement set only makes sense as a set. It takes a few minutes; the tab shows progress and says plainly if a document could not be read.
### Exporting the analytics workbook
Once an analysis exists, **Export analytics workbook** in the tab's overflow menu downloads the full credit spreadsheet: the memo and review summaries, every metric beside the two figures it was computed from, the raw line items with the page each was read from, and the reference sheets that define what Low, Medium and High mean.
It is offered only where an analysis exists -- the workbook is a rendering of one, and there is no such thing as an empty one. Nothing in it is inferred: the credit agency and reputational rows say **Not established** rather than deriving an agency rating from a statement set.
### Changing what the analysis reads
Both the upload dialog and the **Documents used in this analysis** list on the tab let you take a document out of consideration. The file stays on the vendor's Documents tab -- excluding it from a financial analysis is not a reason to delete it.
Removing or adding a document does not blank the figures already on screen. They are still true of the documents they were computed from, so Coverbase keeps them and marks the analysis stale: the tab says the document set has changed and offers **Regenerate**. Nothing is recomputed, and nothing is charged, until you ask for it.
### What you get back
The classification and audit opinion, the periods covered, the issuing legal entity and its auditor, and the full metric battery per fiscal year with the change between years:
* **Balance sheet** -- working capital, current ratio, quick ratio, cash ratio, total funded debt, debt to equity, debt to capitalization, net worth, asset turnover, return on assets, equity multiplier, return on equity
* **Income statement** -- revenue, EBIT, EBITDA, degree of financial leverage, debt to EBITDA, gross and operating margins, net income, net income margin, earnings per share, inventory turnover, AR turnover
* **Cash flow** -- free cash flow, change in cash
Plus a credit-policy risk rating on the four metrics policy rates a partner on -- EBITDA, debt to EBITDA, free cash flow and net worth -- and an overall rating that takes the worst of them, because a partner is only as strong as the metric policy is most worried about.
The tab shows the headline of this. The full tables are available to [assessment report templates](/reporting/template-placeholders#submitted-financial-statements), which is where a credit memo has room to print them.
### How the figures are produced
The model reads the statements and reports **line items** -- figures that appear on a balance sheet, an income statement or a cash flow statement, each with the page it came from. Every ratio, every year-over-year change and every risk rating is then computed by Coverbase, not by the model. A credit memo's arithmetic has to be reproducible from its inputs, and a model asked to divide two numbers is occasionally wrong and always sounds certain.
A figure the statements do not report comes back as **not reported**, never as zero. A zero is a measured result and reads as one.
**Submitted statements are private to your organization.** They never reach the shared company record, so no other Coverbase customer sees them or the score built on them. The vendor's published score -- the one every other organization sees -- is unchanged. Withdrawing the analysis restores your view to that published score and leaves the documents on the vendor's Documents tab.
## Where it appears
The **Coverbase Financial Health Score** card, refreshed on the regular Vendor Intelligence cadence. The **Financial** tab opens the same data full width, with score history, every pillar expanded to its inputs, the full vitals set, and the event timeline.
Financial facts are supplied to control evaluations as authoritative evidence, ranked ahead of web results.
A new vendor request is scored against its registered identity and financial standing before the web is consulted.
Available on the vendor fact-sheet endpoint as `financials.financial_health`, and conversationally through MCP: "what's the financial health score for Acme?"
## Coverage and limits
Coverage is honest about its edges, and these are the ones worth knowing before you build a process on the score.
* **SEC EDGAR covers roughly 7,000 US filers**, often 15-25% of a typical vendor portfolio, on a quarterly cadence with a 40-90 day filing lag. Many private vendors will sit at Tier C, and that is the system working as designed rather than failing.
* **Tier B and C scores are inferred.** They rank vendors sensibly against each other. They do not carry statement-level precision, and the confidence tier is how you tell.
* **Runway is a bound, not a measurement.** The priors behind it are reasoned from what is typical of software companies, not fitted to observed outcomes. Use it to rank and to prompt a question, never as a figure to quote back to the vendor.
* **A stability floor can mask weakness.** An incumbent whose fundamentals are deteriorating, but which has triggered no hard rule, will not read worse than its class floor. That is a deliberate trade against the opposite failure, and it is why the class and any adjustment are published beside the score rather than applied silently.
* **The score is a ranking, not a probability.** The weights are heuristic, chosen to order vendors sensibly rather than fitted against observed failures. Treat the score as "who needs attention first", not as an estimated probability of default.
* **Headcount and funding data lag** and skew toward venture-backed technology companies. A bootstrapped logistics vendor may barely register in them.
* **A scorecard built on one or two signals is capped mid-scale.** Most of such a score comes from an adverse-events pillar that found nothing because nothing was watched, so it reports what it found without reading as reassurance. The cap is published beside the score.
* **Trend features need history.** Where a source publishes only current values, trend inputs are omitted until Coverbase has two snapshots of its own. They are never assumed flat.
* **The score describes the entity that was matched.** If a vendor is a subsidiary and the filings belong to the parent, the score describes the parent's balance sheet. The Corporate Registration card shows which legal entity was bound. See [Vendor Intelligence](/products/vendor-intelligence).
Adverse events are limited to what regulatory filings disclose.
## Availability
The Financial Health Score is an optional feature, enabled per organization. **Contact your Coverbase representative to have it turned on.** Nothing is computed or stored for an organization that doesn't have it enabled.
It pairs with [Vendor Intelligence](/products/vendor-intelligence), which validates the corporate identity the score is computed against, and [Security Intelligence](/products/security-intelligence), which rates a vendor's external security posture. For reading the card day to day, see the [financial health and security intelligence guide](/user-guides/vendor-fact-sheet).
# Findings Manager
Source: https://docs.coverbase.com/products/findings-manager
Intelligence layer over findings across every assessment: remediation tracking and systemic risk pattern detection.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Findings Manager sits on top of the issues raised across all of your assessments. Rather than treating each finding as an isolated to-do, it tracks remediation outcomes over time and surfaces the systemic patterns that span vendors, control sets, and risk domains, so recurring weaknesses become visible instead of being closed one ticket at a time.
## What it does
Roll up findings from every assessment, and from documents, contracts and Radar, into a single view grouped by vendor, control set, assignee or risk level.
Track each finding from open through remediation and verification, including vendor commitments, owners, due dates, and time-bound risk acceptances.
See recurring weaknesses across the portfolio by grouping on control set or vendor: the same control failing across many vendors, or one vendor repeatedly missing the same requirement.
Score findings by severity and urgency, or set the risk level directly, and let the risk level set the due date so reviewers spend time on the findings that matter most.
## How to integrate
List, create, retrieve, and status-sync findings programmatically across assessments and vendors.
Pull findings into your GRC platform, ticketing system, or executive dashboards for remediation reporting.
Ask about findings conversationally. "Which open findings are tied to encryption controls?" or "Show me every vendor with an overdue remediation."
Subscribe to `Finding.*` events and react when findings are created, updated, or resolved.
## Common workflows
Save a filtered view of related findings (for example, every vendor missing a data-breach notification commitment), assign owners, request commitments per vendor, and track closure together rather than as scattered tickets.
Feed aggregated findings into executive and board reporting. Highlight the controls that fail most often across the portfolio so investment goes where it reduces the most risk.
Sync findings to Jira, ServiceNow, or your issue tracker via the Export API and webhooks, keeping remediation work where your teams already operate while Coverbase remains the system of record.
Findings are surfaced through the [Findings API](/api-reference/findings), the [Export API](/export-api-concepts), and the [MCP server](/mcp/overview). They are raised from the issues [Assessment Copilot](/products/assessment-copilot) finds, and from documents, contracts, Radar and other product surfaces. How to work them is in [Findings and remediation](/user-guides/findings-and-remediation).
# Front Door
Source: https://docs.coverbase.com/products/front-door
Triage every intake request before due diligence starts: is the vendor new, can earlier due diligence be reused, does the request need an inherent risk questionnaire, and is the vendor on the Do Not Use list.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Front Door is the first review an intake request gets. Before anyone sends a questionnaire or opens an assessment, the TPRM Office answers four questions on one page: is this a new vendor or one you already have, is there an engagement whose due diligence can be reused, does the request need an inherent risk questionnaire (IRQ), and is the vendor blocked. The answers are recorded as a **disposition**, signed off by two people, and kept in the request's audit trail.
Your Coverbase representative turns on the third-party lifecycle features for your organization.
## What it does
Matches the request against your vendors on tax ID, D-U-N-S number and LEI, which count as deterministic, and on domain and name, which count as probabilistic. Tax IDs stay sealed: Coverbase shows only the last four characters.
Finds the most similar existing engagement by shared services and tags, says whether its completed due diligence is inside your reuse window (12 months unless you change it), and proposes per risk domain whether to reuse it, run an abbreviated review or start again.
A disposition is decided only when one person from the TPRM Office group and a different person from the Supply Chain group have both signed it off. Revising it clears both sign-offs.
While a disposition waits for sign-off, a member of a group that has not signed yet can decline it with a required reason. The disposition goes back to the TPRM Office as a draft, any sign-off already given is cleared, and the TPRM Office and the requester are notified.
Rules read the intake answers and decide whether an IRQ is required and which templates to send. The required IRQs go to the requester once, as soon as the disposition is decided.
A vendor marked Do Not Use can still be requested, but the requester is warned and approving the request needs an override rationale. Adding a vendor to the list and taking it off both need a reason.
When a request started as a purchase requisition in a connected procurement system, the review shows where it came from, its value and category. With budget lines synced, it shows the request's draw against the line and any budget exception the requester asked for.
With Teams approvals on, both sign-off groups can sign off or decline from one Teams card. A decision made in Coverbase updates that card, so it cannot record a second decision.
## How reuse works
A disposition takes one of three forms:
| Disposition | What happens next |
| - | - |
| **Add as new engagement, reuse due diligence** | The vendor's next assessment launched from an assessment plan drops the control sets for every domain marked **Reuse prior due diligence**, copies the prior assessment's scores for those domains, and labels each copied score with the assessment it came from. |
| **Extend the existing engagement** | The request is treated as an amendment to an engagement you already have. No new engagement is created. |
| **Full new due diligence** | Prior results are ignored and due diligence runs in full. |
A reuse decision is applied once, to the next plan-launched assessment for that vendor. Zero Touch assessments do not consume it. After it has been applied, nobody can revise it, and the engagement record shows which domains reused diligence satisfied. If someone scores a reused domain on the new assessment, Coverbase removes the reused label from that domain.
## When a sign-off group declines
While a disposition waits for sign-off, a member of a sign-off group that has not signed yet can click **Decline**, beside **Approve triage**, and write the reason. A decided disposition cannot be declined. Coverbase then:
* returns the disposition to the TPRM Office as a draft and clears any sign-off already given,
* shows on the disposition who declined, for which group, and why, and records the same in the audit trail,
* notifies the TPRM Office and whoever recorded the disposition with the reason, and tells the requester that the TPRM Office is revising the decision.
Nobody can sign off or decline again until the TPRM Office records the disposition again. Recording it again clears the decline and asks both groups to sign off.
## What it does not do
* It does not approve the vendor. Approving the intake is still a separate step, and a vendor created through intake stays in its created status until someone moves it.
* It does not decide on a name match alone. A domain or name match is shown as probabilistic, and only a registry identifier counts as deterministic.
* It does not remove a vendor from the Do Not Use list when an override is recorded. The override applies to that one request.
## Where to go next
Set up the reuse window, sign-off groups and IRQ rules, then triage a request step by step.
Where reused and new diligence come together for the Transaction Owner.
How a request is filed in the first place, from the portal, the API or an AI assistant.
How the IRQ the Front Door sends is scored and who reviews each domain.
# Intake Agent
Source: https://docs.coverbase.com/products/intake-agent
Zero-form intake: requesters ask for a new vendor in Slack, Microsoft Teams, email or their AI assistant, and the Intake Agent fills in what their words say, names approved vendors already doing similar work, asks only for what is missing, and opens the intake for the Front Door.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Your Coverbase representative turns on the third-party lifecycle features, including the Intake Agent, for your organization.
Most people who need a new tool will not fill in a form until they are made to. The Intake Agent meets them where they already ask: a direct message to the Coverbase app in Slack, a chat with your Coverbase bot in Teams, an email to your intake inbox, or their AI assistant through the [MCP server](/mcp/vendor-intake). It reads what they wrote, works out what it can, asks for the rest in the same thread, and opens an ordinary intake request that the [Front Door](/products/front-door) triages like any other.
## What it does
* **Reads the request.** One model call per message works out the vendor, what it is for, the kinds of data it touches (from a fixed list, including **No company data**) and short category terms. Each call is recorded in the [Agent Ledger](/products/agent-ledger).
* **Matches the vendor in code.** An exact name or domain match on one vendor is that vendor. A name matching several vendors is a question to the requester, listing them, and "new" is an answer. No match means a new vendor, created when the intake opens. The model never picks a vendor record.
* **Names similar approved vendors.** Vendors already approved whose use case shares the request's terms are listed in the reply, so the requester and the TPRM Office can reuse before buying. They never block the request.
* **Asks only for what is missing.** If the vendor, the purpose or the data is unclear, the agent replies with what it understood and a numbered question for each gap.
* **Opens the intake.** With everything known, it opens the intake on the same path as the Intake API, with the requester as the requester, your portal's questionnaires, and the conversation as context, starts drafting answers, and replies with the link.
## Who can use it
Only active members of your organization open intakes. Slack checks the member's confirmed address in your installed workspace, Teams the address Microsoft's roster returns for the sender, and email that the sender is a member and that the message passed SPF, because an inbox address is public. MCP uses the signed-in user, with the confirmation every MCP write needs.
## Guardrails
* A channel your organization left off takes nothing, and Slack and Teams requesters are told so.
* A message delivered twice is stored once.
* After five messages with something still missing, the agent stops and points the requester to the intake form.
* Once a conversation opens its intake, the next message in the same thread starts a new request.
## Where to go next
Turn on each channel and follow the conversations.
What happens to the intake next.
The portal and API ways in.
Registering the bot the Teams channel uses.
# Integration Hub
Source: https://docs.coverbase.com/products/integration-hub
Two-way sync with your procure-to-pay and contract lifecycle systems (Coupa, SAP Ariba, Ironclad, Icertis), findings and vendor risk pushed to GRC and ERM tools (Archer, ServiceNow IRM, a REST risk register), Microsoft Teams notifications and approvals, and the Intake Agent, with field mappings, a sync log and a steward queue for suppliers that do not match.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Your Coverbase representative turns on the third-party lifecycle features, including the Integration Hub, for your organization.
The Integration Hub connects Coverbase to the systems your purchases and contracts already move through. Requisitions in your procurement system open intake requests, supplier records link to your vendors, executed contracts in your contract lifecycle system mark the Coverbase contract executed, and Coverbase writes its risk tier, approval status and contract risk back to the provider. Every connection has **Field Mappings**, **Sync Log**, **Steward Queue** and **Authentication** tabs.
## Providers
| Provider | Category | Direction | What syncs |
| - | - | - | - |
| [Coupa](/integrations/guides/coupa) | Procure-to-pay | Two-way | Requisitions, suppliers, contracts and budget lines in; supplier risk tier and approval status, and contract risk rating, out |
| [SAP Ariba](/integrations/guides/sap-ariba) | Procure-to-pay | Inbound only | Supplier master data with qualification status, and sourcing events |
| [Ironclad](/integrations/guides/ironclad) | Contract lifecycle | Two-way | Records and their signed copies in; risk rating, required clause pack and blocking issues out |
| [Icertis](/integrations/guides/icertis) | Contract lifecycle | Two-way | Agreements and their executed copies in; risk rating, required clause pack and blocking issues out |
| [Archer](/integrations/guides/archer) | GRC and ERM | Two-way | Findings as issues and vendors as risks out; each record's status back |
| [ServiceNow IRM](/integrations/guides/servicenow-irm) | GRC and ERM | Two-way | Findings as GRC issues and vendors as risks out; each record's state back |
| [ERM risk register](/integrations/guides/erm-register) | GRC and ERM | Outbound | A risk per rated vendor, to a REST register you describe |
| [Microsoft Teams](/integrations/guides/microsoft-teams) | Messaging | Outbound, plus card actions | Notifications you choose, posted to a channel as Adaptive Cards; with your bot, approvals from the card and intake chats |
## How a sync works
Each connection syncs on its own interval (every 60 minutes unless you change it, and no more often than every 15 minutes), and on demand with **Sync now**. A provider that can call a webhook can also nudge a sync when a record changes. A webhook from a contract lifecycle system that names a contract syncs only that contract, including a contract whose record ID is `0`. Inbound passes run first, in a fixed order, so later passes can find suppliers through links the supplier pass made:
1. **Suppliers** link to a vendor and record its approved supplier list status.
2. **Requisitions and sourcing events** open a draft intake request carrying the value, category and requester, and pass the supplier's tax ID, D-U-N-S number and LEI to the Front Door.
3. **Contracts** create or update a Coverbase contract and, when executed in the provider, mark it executed through the same path DocuSign uses, so the executed notice and accounting packet fire the same way.
4. **Budget lines** (Coupa) record the amount and committed spend that Spend Controls and the intake budget step read.
Outbound runs last, and pushes a record only when its values changed since the last push. After the push, an Archer or ServiceNow IRM connection reads back the status of every issue and risk record it holds. Coverbase stores that status and does not change the finding's own status from it. Each record is written on its own, so one bad record fails alone, and the sync log says which record failed and why.
## Matching suppliers
A name alone never links a supplier. A tax ID, D-U-N-S number or LEI match links on one hit, and a domain links only when no stronger identifier points to a different vendor. Every match is among your organization's own vendors. Anything else goes to the **Steward Queue**, where someone links it to the right vendor or dismisses it. Once linked, a supplier is never re-matched. The queue filters by system, reason, age and name, and links or dismisses many records at once as a background job that reports, for example, "12 linked, 3 need a decision". A contract that arrives before its supplier is linked waits, and is filed against the vendor, with its executed copy, as soon as the steward links the supplier.
## Approvals in Teams
With a Coverbase bot registered in your Azure tenant, the Microsoft Teams connection posts three requests with **Approve** and **Decline** buttons: a Front Door disposition waiting on a sign-off group, a finding's acceptance chain waiting on a decision, and exit plan evidence waiting on its approver. People decide in Teams as themselves, with their own Coverbase permissions. A Front Door card is posted once for both sign-off groups and is replaced with the outcome whether the sign-off or decline happens on the card or in Coverbase. See [Microsoft Teams](/integrations/guides/microsoft-teams).
## The required clause pack
The clause pack written to a contract lifecycle system lists the high and critical severity clauses of your active clause sets, up to 25, by clause ID and name. It is the same list for every contract. Blocking issues are the titles of the vendor's open findings, up to 20.
This list is the same for every contract written to a contract lifecycle system. The clauses a particular engagement requires, from its own risk results and open issues, are its [clause pack](/products/clause-pack), shown on the engagement's **Contract** tab.
## Credentials and webhooks
Credentials go to a secrets manager when you save them and are never returned. The page only says which fields are set. A connection's webhook signing secret is shown once, when you create or rotate it. Inbound webhooks must be signed (see [Integration credentials and signing](/security/integration-credentials#inbound-integration-webhooks)), and a webhook body is never trusted as data: it only starts a sync that re-reads the record from the provider.
## Where to go next
Connect a provider, review its field mappings, read the sync log and work the steward queue.
Where a synced requisition shows up for the TPRM Office.
Everything Coverbase connects to, and which systems have a connector.
How credentials, signing secrets and webhooks are protected.
# Internal control monitoring
Source: https://docs.coverbase.com/products/internal-controls-monitoring
Coverbase against your own applications: evidence collected from live admin consoles, 392 internal controls out of the box, drift detection between runs, and internal findings sharing the same findings, workflow and reporting machinery as third-party risk.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Most risk platforms make you run two programs: one for your third parties and one for yourself, in different tools, with different evidence, different findings and different reporting. Coverbase runs both on the same objects.
The third-party half is what Coverbase is best known for. This page is about the other half: evaluating the controls inside the applications **you** run, on the same control model, feeding the same findings, workflows, dashboards and audit trail.
Internal control monitoring is delivered by [Coverbase Inspect](/products/agentic-inspect) and is enabled per organization. If you do not see **Inspect** in your navigation, ask your Coverbase team to switch it on.
## Evidence read from the admin console
Traditional compliance evidence collection is a screenshot request. Someone is asked whether MFA is enforced, they open the admin console, they screenshot it, they paste it into a ticket, and a quarter later nobody knows whether it is still true.
Inspect signs in to the application tenant with **read-only** credentials and reads the answer off the live admin console itself, then records what it saw with chain-of-custody metadata: the screenshot, the source URL, the timestamp, and the request context.
The inspection identity holds a read-only role inside each target application. Authentication and authorization are separate concerns: your identity provider authenticates the inspection identity, and the target application's own read-only role is what bounds it.
An observation that could not be obtained still exists and still says why: unsupported, authentication required, forbidden, inconclusive, or failed. An application that does not sell a capability is not marked down for lacking it.
Each control gets its own run, so one control failing to collect evidence never stops the rest of the set.
**Explore** establishes whether the evidence can be collected at all. **Evaluate** adjudicates it against the control expectation and your scale. Progress and outcome stay separate facts.
## 392 internal controls, ready to run
The [Internal Controls Library](/control-library#internal-controls-library) ships **22 templates spanning 392 controls**, so a program does not start from a blank control set.
| Area | Templates |
| - | - |
| Baseline | Security Configuration Baseline |
| Identity and access | Identity & Authentication Baseline, Privileged & Administrative Access, Application Access Lifecycle |
| Scope | Application Scope & Feature Drift, Integrations, OAuth & Connected Apps |
| Data | Data Services & Storage Surface, PII Data Scope & Handling, Retention Residency & Deletion, Export Sharing & External Collaboration |
| Regulated data | PHI & HIPAA Application Safeguards, GDPR & Cross-Border Privacy |
| AI | AI Features & Model Usage, AI Agents Copilots & Autonomous Actions |
| Resilience | Operational Resilience & Failover, Performance & SLA Conformance, Audit Logging & Monitoring |
| Commercial | Usage Seats & Licensing |
| Application classes | CRM Application Controls, HRIS & Payroll Application Controls, Financial Services Application Controls |
| Framework-derived | CIS Controls v8.1 SaaS Baseline, citing the CIS safeguard and the NIST SP 800-53 controls behind each control |
Each control states an expectation carrying its own threshold, names the admin surface that answers it plus the alternate labels different vendors use for the same screen, and defines what counts as incomplete. Fork a template and it becomes your control set, fully editable, exactly like a vendor framework.
## Drift between runs
Point-in-time evidence decays the moment an administrator changes a setting. Inspect's **Drift** mode compares a run against a compatible earlier one and reports what moved.
* **Outcome** is `exact`, `changed`, or an explicit reason it could not be compared, never a silent pass.
* **Materiality** is judged on a change: material, immaterial, or inconclusive, with a summary of what differs. A renamed label is not the same event as a disabled control.
* **Re-run on a cadence you choose**, so "is MFA still enforced on the finance system" is a question your evidence answers this week rather than last audit.
A material change emails the person who started the inspection, or who owns its schedule. To track it to closure, run **Evaluate** and create a finding from the control, which then has an owner, a due date and the same workflows and dashboards as third-party findings.
## One risk model, both sides
This is the part that matters for an enterprise risk view. Internal and third-party risk are not parallel systems in Coverbase; they are the same system pointed at two populations.
| Shared object | Internal | Third party |
| - | - | - |
| **Control sets** | Internal Controls Library, forked and edited | Vendor Controls Library: SOC 2, ISO 27001, NIST, PCI, the Interagency Guidance, and 60-plus more |
| **Evaluations** | Read from your admin consoles | Read from vendor evidence, attestations and questionnaires |
| **Risk domains** | The same domains, so an identity weakness scores in the same place whoever owns it | Same |
| **Risk scales** | Your scale | Your scale |
| **Findings** | Assigned, tracked, escalated, closed with evidence | Same objects, same queue |
| **Workflows** | Same trigger, condition and action engine | Same |
| **Reviews and approvals** | Same gates, same outcomes, same attribution | Same |
| **Dashboards and reporting** | Same charts, filtered by population | Same |
| **Audit trail** | One trail | One trail |
The practical consequence: a single dashboard can show that your own privileged-access control is weak **and** that three critical vendors have the same gap, scored on the same scale, in the same risk domain. Answering that across two separate systems normally means exporting both into a spreadsheet.
Start with the applications that already carry your regulated data. Inspect the identity provider, the CRM, the HRIS and the finance system against the Identity & Authentication Baseline and Privileged & Administrative Access sets. Those four applications and two control sets usually surface more than the first year of a manual internal control program does.
## Compliance evidence automation
Where an internal audit or a compliance program needs evidence on a schedule rather than a request:
Fork the internal templates that match your framework, edit expectations to your thresholds, and attach them to the applications in scope.
Evidence is gathered from the live console, with the screenshot, source and timestamp attached to each observation. Nobody is asked for a screenshot.
Evaluate produces the judgment against your scale. Create a finding from any control whose evaluation raised an issue, and it gets an owner, a due date and a workflow behind it.
Subsequent runs compare against the baseline. A material change sends an alert; an immaterial one is noise that does not reach anyone's inbox.
The same [evidence packaging](/reporting/due-diligence-file) that produces a third-party due-diligence file produces the internal control evidence package, with the audit trail behind it.
## Related
The inspection engine itself, and the vendor-facing half of it.
Every internal and vendor control set, with counts and sources.
The shared findings and remediation surface.
How both halves map to banking supervisory expectations.
# License and accreditation
Source: https://docs.coverbase.com/products/license-and-accreditation
How Coverbase decides which licenses a vendor needs, which public registers it searches for them, and how it reports every register it checked.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A vendor that collects debts, originates mortgages, adjusts claims or rewires a building usually needs a license from the state or country where it works. The license lives on the issuing regulator's own register, not on the vendor's website. Coverbase works out which licenses the vendor's business calls for, searches the registers that issue them, and shows you what each register says.
Sanctions and debarment lists are not part of the license lookup: the Zero Touch sanctions screen checks the vendor against them separately. Enforcement actions and exclusions the license lookup finds are shown first.
The most common mistake is reading an empty result as a clean one. A register that was not read, or that publishes no lookup, says nothing about the vendor. The page lists every register planned for the vendor and what happened at each one, so you can tell the two apart.
## Where it runs
The **Licenses** tab of a vendor's [Vendor Intelligence](/products/vendor-intelligence) section. License records are gathered with the corporate registration research and refresh with it. Refreshing that research checks the registers again.
A [Zero Touch](/products/zero-touch-assessments) run that includes the **Licenses** section (on by default) waits for the vendor's license research, then grades the license controls from the same records the **Licenses** tab shows.
Research waits for a description of the vendor. Until the vendor has an industry or a description on file, nothing is stored, because registers chosen from nothing would read as "no license register applies".
## How a lookup runs
```mermaid theme={null}
flowchart LR
A["Vendor description and headquarters"] --> B["Lines of business, states and countries"]
B --> C["Plan: the register for each line in each jurisdiction, plus entity, enforcement and exclusion registers"]
C --> D{"Register"}
D -->|"Searchable"| E["Search under up to 3 spellings of the vendor's names"]
D -->|"Not read automatically"| F["Lookup link and the reason"]
D -->|"No license there, or no public lookup"| G["Noted on the list of registers"]
E --> H["Keep records that match the whole name; enforcement and exclusion lists need the exact legal name"]
H --> I["Records and registers checked, on the Licenses tab and in the Zero Touch review"]
F --> I
G --> I
```
A model reads the vendor's name, headquarters and description the way a reviewer would, and names every licensed line of business the vendor itself is in. It judges the vendor's own activity, never its customers': a consulting firm that serves banks is not a bank, and software, data, research and consulting need none of these licenses. When the description does not say what the vendor does, it chooses none and says the description is too thin. Its one sentence of reasoning is kept and shown when no register applies.
The same read gives the US state of the headquarters, the US states the description confines the vendor to (a local practice, a regional bank, "licensed in Texas and Oklahoma"), whether it serves the US nationwide, and the countries outside the US where it is headquartered or operates. A US vendor that names no states is searched in every state, because licensed firms rarely list them.
For each line of business, the plan takes the register that licenses it in each state and the national register for that line. It adds the business entity filing in the headquarters state, financial enforcement lists when a line is financial, Medicaid exclusion lists when a line is in health care, and the company registry and financial regulator of each country outside the US. Sanctions lists and SEC filing indexes are never planned, because they hold no license.
Each register is searched by business name under up to three spellings of the vendor's names. A register gets 30 seconds, the whole lookup gets 150 seconds, and Coverbase sends at most three searches at a time to any one register's site.
A register's search returns every firm that shares a word with the query. Only records that match the vendor's whole name are kept. See [How records are matched](#how-records-are-matched).
Every planned register lands on the **State and National Registers** list with its outcome. A register that was not searched automatically carries a **Look up** link and the reason, so you can check it yourself.
## Supported lines of business
The classifier chooses from the lines below. A category applies in every country: an HVAC installer in Australia is a specialty contractor, and a recruiter in India is staffing or PEO.
| Category | The vendor... |
| - | - |
| **Investment or securities** | Manages money, gives investment advice, or brokers or deals securities |
| **Bank charter** | Is a chartered bank, trust company or credit union |
| **Mortgage lender** | Originates or brokers residential mortgage loans |
| **Mortgage servicer** | Services mortgage loans for others |
| **Money transmitter** | Transmits money, sells payment instruments or stored value, or exchanges virtual currency for customers |
| **Consumer lender** | Makes consumer, installment, payday or small loans |
| **Debt collector** | Collects consumer or commercial debts owed to others |
| **Debt buyer** | Buys charged-off debt and collects it |
| **Check casher** | Cashes checks or offers deferred deposit |
| **Sales finance** | Finances or buys retail installment contracts (auto or goods) |
| Category | The vendor... |
| - | - |
| **Insurance carrier** | Underwrites insurance as an insurer or reinsurer |
| **Insurance agency** | Sells, solicits or negotiates insurance as an agency or broker |
| **Insurance adjuster** | Adjusts insurance claims as an independent or public adjuster |
| **Title agent** | Is a title insurance agency |
| **Title insurer** | Underwrites title insurance |
| **Escrow agent** | Holds escrow for real estate or other transactions |
| **Premium finance** | Finances insurance premiums |
| **Third-party administrator** | Administers insurance or benefit plans for insurers or employers |
| **Surplus lines broker** | Places surplus lines insurance |
| Category | The vendor... |
| - | - |
| **Real estate brokerage** | Brokers, lists or leases real estate for others |
| **Appraisal management** | Is an appraisal management company |
| **Appraisal firm** | Performs real estate appraisals itself |
| **Auctioneer** | Auctions property |
| **Property management** | Manages rental property for owners, including property preservation |
| **Community association management** | Manages HOAs or community associations |
| **Home inspection** | Performs home inspections |
| **Foreclosure trustee** | Acts as trustee in non-judicial foreclosures |
| Category | The vendor... |
| - | - |
| **General contractor** | Builds, repairs or renovates commercial work |
| **Residential contractor** | Builds, repairs or renovates residential work |
| **Specialty contractor** | Performs trade work such as electrical, plumbing, HVAC or roofing |
| **Lead and asbestos abatement** | Performs lead or asbestos abatement |
| **Mold remediation** | Performs mold remediation |
| **Pest control** | Performs pest control |
| **Locksmith** | Performs locksmith work |
| Category | The vendor... |
| - | - |
| **Public accounting** | Is a CPA firm offering audit, attest or tax services |
| **Legal practice** | Is a law firm |
| **Engineering firm** | Offers engineering services |
| **Architecture firm** | Offers architecture services |
| **Surveying firm** | Offers land surveying services |
| **Private investigation** | Offers private investigation |
| **Security guard services** | Offers security guard services |
| **Process server** | Serves legal process |
| **Alarm systems** | Installs or monitors alarm systems |
| Category | The vendor... |
| - | - |
| **Pharmacy** | Dispenses drugs |
| **Drug wholesale distribution** | Distributes or warehouses drugs |
| **Health facility** | Operates a licensed health facility |
| **Healthcare provider** | Bills Medicaid or Medicare for care it provides |
| Category | The vendor... |
| - | - |
| **Motor vehicle dealer** | Sells vehicles |
| **Vehicle title service** | Processes vehicle titles and registrations |
| **Salvage vehicle auction** | Auctions salvage vehicles |
| **Electronic lien and title** | Provides electronic lien and title services to lenders and DMVs |
| **Waste hauler** | Hauls waste |
| **Cannabis** | Operates in cannabis |
| **Staffing or PEO** | Supplies staff or acts as a professional employer organization |
| **Charitable solicitation** | Solicits charitable donations |
| **Cloud service provider** | Sells cloud services to state governments |
| **Diversity certification** | Says it is certified as minority, women or disadvantaged owned |
| Category | The vendor... |
| - | - |
| **Energy supplier** | Supplies retail energy |
| **Telecom carrier** | Provides telecom service |
A category is chosen only for an activity the description states or the company's name plainly carries. The classifier never adds the lines a company of that kind usually has: a bank is **Bank charter**, plus mortgage lending or insurance only when the description names them.
Research stored before these lines existed may show a broader category, such as **Mortgage lending or money transmission**, **Insurance, title or escrow** or **Contracting or property services**. Each is searched as every line it covers.
## The registers behind each line
Coverbase's register catalog was researched register by register: about 1,250 licensing, entity, enforcement, exclusion and certification registers across all 50 states, DC, Puerto Rico, Guam, the US Virgin Islands, federal agencies, international bodies and 17 other countries. About 600 of them are searched automatically. Every other one still appears on the vendor's list of registers with a link to its lookup.
A few examples from each family:
| Family | Example registers |
| - | - |
| Financial services | NMLS, the national register for state mortgage, money transmitter, consumer finance and debt licenses; state banking and financial regulators such as the New York Department of Financial Services, the California Department of Financial Protection and Innovation and the Texas Department of Banking; FDIC BankFind; the SEC's Investment Adviser Public Disclosure and broker-dealer list |
| Insurance, title and escrow | State insurance departments such as the California and Texas Departments of Insurance; the NAIC State Based Systems license lookup |
| Real estate and appraisal | The Appraisal Subcommittee's national registry of appraisal management companies; state real estate and appraiser boards such as the Texas Real Estate Commission; the Florida Department of Business and Professional Regulation |
| Contractors and trades | State contractor boards such as the California Contractors State License Board, the Washington Department of Labor and Industries and the Texas Department of Licensing and Regulation |
| Professional services | NASBA CPAverify for CPA firms; state engineering, architecture and surveying boards such as the Texas Board of Professional Engineers and Land Surveyors; the New York Office of the Professions; California's Bureau of Security and Investigative Services |
| Health care | State boards of pharmacy such as the Texas State Board of Pharmacy; state health facility registers such as the New York Department of Health; CMS laboratory and home health records |
| Vehicles | State DMV dealer lists such as the Texas Department of Motor Vehicles; state electronic lien and title provider lists |
| Commerce and government programs | FMCSA operating authority for waste haulers; the California Department of Cannabis Control; the IRS list of certified PEOs; state charity registries such as the California Attorney General's Registry of Charities and Fundraisers; FedRAMP, GovRAMP and TX-RAMP for cloud providers; SBA certifications and state MWBE programs |
| Telecom and energy | State utility commissions such as the Public Utility Commission of Texas, the California Public Utilities Commission and the New York Public Service Commission; FCC registration and Form 499 filer records |
These are read for every vendor whose lines or location call for them:
| Register family | When it is read | Examples |
| - | - | - |
| **Business entity filings** | Every vendor with a US headquarters, in its headquarters state | State business entity registers such as the Delaware Division of Corporations and Florida's Sunbiz |
| **Enforcement actions** | When any line is financial, in each state planned and nationally | OCC, Federal Reserve Board, SEC administrative proceedings and litigation releases, CFPB, FinCEN; state regulators' enforcement orders such as the New York Department of Financial Services |
| **Exclusion lists** | When any line is in health care, in each state planned | State Medicaid exclusion lists such as New York's Office of the Medicaid Inspector General and California's Medi-Cal Suspended and Ineligible Provider List |
| **Company registries and financial regulators abroad** | For each country outside the US where the vendor is headquartered or operates; the financial regulator when a line is financial | UK Companies House, the FCA Register and the ICO data protection register; Australia's ASIC, ABN Lookup and AUSTRAC; Corporations Canada and the Canadian Securities Administrators' national registration search; Germany's Handelsregister and BaFin; Singapore's ACRA and MAS; India's RBI and SEBI; Ireland's Companies Registration Office and Central Bank |
The countries with a planned company registry are Australia, Brazil, Canada, France, Germany, Hong Kong, India, Ireland, Israel, Japan, Luxembourg, Mexico, the Netherlands, the Philippines, Singapore, Switzerland and the United Kingdom.
## How records are matched
A register's search is a loose text search, so it returns every firm that shares a word with the query. A record is only the vendor's when its whole name is one of the vendor's names.
**Which names are searched.** The vendor's name, its aliases, every name your organization gave the vendor (often the legal name, such as "Example Holdings, LLC" for the brand "Example"), and the official name from the vendor's corporate registration match. The registration name is left out when it comes from another country or shares no word with the vendor's names, because that marks a namesake.
**How each name is spelled.** Many registers only match the spelling they are given. Each name is searched as written, without its legal form, without a web domain, with "&" and "and" swapped, and with its words joined. A register gets up to three of these spellings, taken across the vendor's names so the first name cannot use them all.
**When a record binds.** A record binds when it carries one of the vendor's legal names with its legal form, however the register spaces it. Otherwise the name with its legal form set aside must match a distinctive name (more than one word), and every record so named must carry one legal form: "Clear Capital LLC" next to "Clear Capital Inc." binds neither. A trade name or d/b/a that the register lists beside the holder binds on the same rules. A one word brand never binds on its own.
**Enforcement and exclusion lists are stricter.** A record on an enforcement or exclusion list binds only on the exact name, legal form included. A namesake on an exclusion list ("Example Group FZCO") is never treated as the vendor ("Example Group Inc.").
Some national registers are also searched under the parent company's name. Those records are labeled **Parent company**.
## Reading the Licenses tab
The tab reads top to bottom: a verdict, the adverse records, the records found, then every register planned for the vendor.
The headline is one of: **No license register applies**, **License held on a register Coverbase does not read**, **No license record found**, a count of enforcement actions or exclusions on record, a count of licenses not active, a count of licenses with no published standing, or a count of active licenses across a number of jurisdictions. Enforcement actions and lapsed licenses are shown as critical. A callout under it says what to ask the vendor.
**No license record found** is not a clean result. A vendor offering a licensed service usually holds a license, so confirm the legal entity or ask the vendor for its license numbers.
Appears only when a regulator's enforcement action or an exclusion list names the vendor exactly. Read each action and ask the vendor how it was resolved.
One section per register, with every record it holds for the vendor: **Holder**, **Jurisdiction**, **License** (number and license type), **Status**, **Expires** and **Record**, which opens the register's own page. **Active** and **Not active** come from the register's status, or from the expiry date when the register gives no status. **Status not stated** means the register published neither. A record held by the parent company says so under the holder.
Every register planned for the vendor's lines of business, with **Line of Business**, **Jurisdiction**, **Register**, **Outcome** and a **Look up** link. Entity and enforcement registers are listed under **Entity, enforcement and national registers**. A summary line gives the number of registers, then how many were read, how many to check by hand, how many did not answer, and how many need no license or have no lookup.
**Registers Checked** lists the other registers searched by name, such as NASBA CPAverify, the FCA Register or state license data. **Not Checked** lists each register that did not answer and each one you need to check by hand. When more than four registers for one line need checking by hand, they are summarized as one line that names the jurisdictions, and each is linked on the **State and National Registers** list.
### Outcomes
| Outcome | What it means | What to do |
| - | - | - |
| A record count, or **No record matched** | The register was searched. The count is the records that matched the vendor; a search that matched nothing is shown in gray, not green. | Read the records. No match on a register that applies is a question for the vendor. |
| **Did not answer** | The register failed or ran out of time on this run. | Refresh later, or use **Look up**. Records it returned on an earlier run are kept, so an outage never reads as a license having gone. |
| **Check by hand** | The register is not searched automatically. The note says why. | Use **Look up** and search the vendor's legal name yourself. |
| **Not required there** | That state or country does not require what the register column names, such as a law firm registration. A lawyer's own bar admission is a separate check, listed under **Not Checked**. | Nothing. |
| **No public lookup** | The jurisdiction licenses the line but publishes no way to look it up. More than three such rows for one register are shown as one row with the number of jurisdictions. | Ask the vendor for a copy of the license. |
## Zero Touch license controls
The **Zero Touch License and Accreditation Validation** template asks the four license and accreditation controls, plus company identity, registration and ownership, disciplinary history and regulatory actions. A run that includes the **Licenses** section grades these controls from the vendor's stored license records, the same ones the **Licenses** tab shows, rather than from a second lookup.
| Control | Asks |
| - | - |
| ZT-LIC-01 | Every entity-level license the service requires is active on the issuer's register |
| ZT-LIC-02 | Those licenses cover every jurisdiction the vendor serves |
| ZT-LIC-03 | Each license is held by the contracting entity or a named affiliate that delivers the service |
| ZT-LIC-04 | Voluntary accreditations the service relies on (peer review, PCAOB, SOC reports) are current |
* The requirement comes from what the vendor does, never from a word in its name. When the license research finds that nothing the vendor does needs a license, and no register lists one, ZT-LIC-01 and ZT-LIC-02 are compliant, each with its own finding and the research's reason, and ZT-LIC-03 is not applicable on every scale, left out of the score where the scale has no Not Applicable level. This holds even when the vendor's own website cannot be read.
* A required license shown inactive, expired, suspended or revoked, with no active record beside it, is not compliant.
* A jurisdiction whose only records are inactive is a gap on ZT-LIC-02. An inactive record next to an active one in the same jurisdiction is history.
* A register that was not read is listed as a gap for the vendor to fill with a copy, not reported as a missing license.
* The automated review labels enforcement actions and exclusions as adverse.
A run that leaves the **Licenses** section out skips the license controls.
## Limits
* **Public registers only.** Coverbase reads what regulators publish. A license on a roll with no public lookup, such as a state bar admission, needs a copy from the vendor.
* **Registers that are not read automatically.** Some registers sit behind a CAPTCHA or a login, or are not read automatically yet. They are listed with a **Look up** link rather than left out.
* **Register outages.** A register that does not answer on a run is marked **Did not answer**, and its earlier records are kept until it answers again.
* **Names that differ from the legal name.** A license held under a name Coverbase does not know, such as an affiliate's, is not matched. If the vendor's legal name is missing or wrong, correct the corporate registration match on the **Registrations** tab and refresh. See [Corporate Registrations](/products/corporate-registrations).
* **A description that is too thin.** If the vendor's description does not say what it does, no line of business is chosen and only the entity filing and company registry apply.
## Related
The validated corporate identity every other answer is computed against.
The legal entity whose names the license lookup searches.
Triage assessments that grade the license controls from these records.
The screen by screen walkthrough.
# Monitoring plans and scorecards
Source: https://docs.coverbase.com/products/monitoring-plans
A schedule of ongoing monitoring for every active engagement: which activities a vendor owes at its tier, who owns each, when each is next due, how signals re-time it, the IRQ refresh with its answer diff, owner attestation, performance scorecards, contract obligations, and the Monitoring workbench for working them in bulk.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Your Coverbase representative turns on the third-party lifecycle features, including monitoring plans, for your organization.
A monitoring plan is the schedule an engagement follows once it is live. Your TPRM Office sets a cadence matrix once, by tier and activity, and every engagement gets a plan from it: which activities it owes, who owns each one, and when each is next due. A service that is not part of any engagement gets its own plan.
## What it does
For each tier of your risk scale, an interval in months and an owner (Transaction Owner or TPRM Office) for each activity: IRQ refresh, performance scorecard, owner attestation, evidence request and contract review. An organization that never saved a matrix gets a default, highest risk tier first.
The due diligence reassessment on the plan mirrors your reassessment schedule rather than keeping a second date. Moving it on the plan moves the reassessment schedule, so the reassessment is created on the new date. Continuous monitoring is Radar, always on while Radar is on for the vendor.
A Radar alert at or above a severity you choose, or a reassessment trigger, pulls the activities you name forward. The move is the monitoring agent acting on its own, so it also needs the **Re-time monitoring from feed signals** [agent policy](/products/agent-ledger#agent-policies), off by default. The move is applied at once and recorded with the signal that caused it, and the TPRM Office can keep it or revert it within an undo window.
The Transaction Owner refreshes the inherent risk questionnaire from the last approved answers. The TPRM Office sees every answer that changed, each domain's score and level before and after, newly in-scope domains and any tier change, then confirms. A new domain or a higher tier raises a reassessment straight away.
One question on the plan's cadence: is this still in use? Every answer is logged with the user and time. **Start offboarding** files a real offboarding request and pauses the plan.
A rubric bound to a tier and service category, scored by the respondents you name, with SLA adherence from the vendor's SLAs. A weighted score below your threshold is flagged.
## When a plan exists
A plan is generated when an engagement goes active, or a service outside any engagement goes active or completes. An executed contract, an approved engagement IRQ or a manual request from the TPRM Office also generates one before that. A daily sweep fills in any live engagement or service that has no plan.
A plan is re-planned when the tier moves, an IRQ is approved or a refresh is confirmed. Activities the TPRM Office edited keep their interval, owner and due date. The rest follow the matrix.
## Pausing
An engagement or service in a canceled status, an expired engagement, or any status you list under **Pausing Statuses** (such as On hold) pauses its plan. Pausing turns the vendor's Radar monitoring off only when no other live engagement or active plan needs it, and resuming turns back on only what the pause turned off. While every plan for a vendor is paused, reassessments are neither created nor reminded. On resume, due dates move out by the time spent paused.
## Notices
Each activity's owner is told before it is due, by the number of days you set. Past the overdue window, the owner and the TPRM Office are escalated to. Each due date is announced once. The sweep that sends these runs every day at 13:30 UTC.
## Comparing questionnaire submissions
The IRQ refresh shows a side-by-side diff of the refreshed answers against the last approved IRQ: every answer changed, added, removed or left alone, each answer's score, and each domain's score before and after. The same comparison is on the vendor's **Questionnaires** tab: **Compare** any finished submission with the vendor's earlier submission of the same questionnaire.
## Contract obligations
When a contract is signed, each obligation in its [clause pack](/products/clause-pack) that the signed contract carries becomes an activity on the engagement's plan, on the cadence its clause rule names. It is an ordinary activity. Notices, escalations, completion and pausing apply to it unchanged, and the timeline shows the obligation's own text.
## The Monitoring workbench
**Monitoring** in the left navigation lists every scheduled activity and every plan across your engagements and services, filtered by activity, due window and owner, with what you can see following your vendor access. The TPRM Office can **Reschedule** selected activities to a date or by a number of days, and **Send scorecards** now instead of at their notice window. Small selections run at once. Larger ones run in the background with progress. Each activity that cannot move says why, such as a paused plan or a date inside a reassessment's collection time, and the rest still go through.
## Where to go next
Set the cadence matrix and rubrics, read a plan, refresh an IRQ and score a scorecard.
The signals that re-time a plan.
What Start offboarding sets in motion.
The engagement page the plan lives on.
# Obligations Tracker
Source: https://docs.coverbase.com/products/obligations-tracker
Track the obligations your organization takes on when engaging third parties: CUECs, legal terms, SOW duties, and technical controls.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Obligations Tracker keeps a living record of what your organization is responsible for when it engages a third party. Complementary user-entity controls (CUECs), contractual and legal terms, statement-of-work duties, and technical controls are extracted, assigned, and monitored so commitments don't fall through the cracks between procurement, legal, and the control owners who have to satisfy them.
## What it does
Capture obligations from SOC 1 and SOC 2 Type 2 reports (CUECs) and from contract documents such as MSAs, SOWs and order forms (shared responsibilities) into structured, trackable records.
Assign each obligation to an owner with a due date and status, so responsibility for every commitment is explicit and auditable.
Track complementary user-entity controls surfaced in vendor SOC 1 and SOC 2 reports, match them to your internal controls, and confirm your side of each shared-responsibility control is satisfied.
Monitor due dates and satisfaction across vendors, ask a business unit to acknowledge an obligation, and, with the Risk module, raise an overdue or unacknowledged obligation as a risk signal.
## How to integrate
List, retrieve, and filter obligations and their status programmatically.
Pull obligation commitments (who acknowledged what, and by when) into your GRC platform, contract management system, or compliance dashboards.
Query obligations conversationally. "Which CUECs are unsatisfied for our tier-1 vendors?" or "What obligations are due this quarter?"
Subscribe to `Obligation.*` events and react when obligations are created, updated (including reassignment), or deleted.
## Common workflows
When a vendor's SOC 2 lists complementary user-entity controls, Obligations Tracker captures each one, assigns the responsible owner on your side, and tracks confirmation so shared-responsibility gaps are closed before they become audit findings.
Obligations extracted by [Contract Guardian](/products/contract-guardian) flow into the tracker, where SLAs, audit rights, and notification duties are assigned and monitored against the live engagement.
When an amendment or a new report arrives, extract obligations from it, compare them with the ones already on file for the vendor, and archive or reassign what changed so the obligation surface stays aligned with the current agreement.
Obligations are surfaced through the [Obligations API](/api-reference/obligations) and the [MCP server](/mcp/overview), and their commitments through the [Export API](/export-api-concepts). Obligations extracted by [Contract Guardian](/products/contract-guardian) feed directly into the tracker. How to work them is in [Obligations](/user-guides/obligations).
# Offboarding and continuity
Source: https://docs.coverbase.com/products/offboarding-and-continuity
The end of an engagement, and the steps either side of the contract: the executed contract handoff, continuity plans for critical engagements, and offboarding with an exit plan that closes only on approved evidence.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Ending a vendor relationship takes more than archiving a record. The data has to come back or be destroyed, access removed, integrations disconnected, and the contract terminated with the right notice. Coverbase builds that work from what the engagement had, assigns each step, and closes a step only when its evidence has been approved. The same module handles the steps around the contract: the handoff that files the executed agreement, and the continuity plan a critical engagement carries.
Your Coverbase representative turns on the third-party lifecycle features for your organization.
## What it does
A reason, a business justification and an optional requested date, approved by the TPRM Office and, once its group is named, Supply Chain. Marking an engagement not in use opens one automatically.
Steps for the data the vendor held, the access it had, its integrations, its contracts and the continuity plan, each with an owner and an approver. **Rebuild from current data** adds new steps without losing work already done. Evidence and approvals can be given for many steps at once, and **Remind owners** chases everyone a step waits on.
A step closes only when its evidence is submitted and its approver approves it. Document steps need a file, sign-off steps a note, and the data step the vendor's signed destruction certificate.
The vendor signs a data destruction certificate in the supplier portal. The signatory, title, time and a digest of the certificate are recorded, and approval is refused if the signed certificate has changed since it was submitted.
In-flight due diligence and a pending contract handoff stop when offboarding starts. When the plan closes, the engagement, its services, the vendor, Radar and the monitoring record are set inactive or closed, but only where no other live engagement still needs them.
An engagement at the top of its risk scale gets a draft continuity plan and a task for its Transaction Owner: backup suppliers, an exit strategy, a recovery time objective, resiliency notes and transition steps. Its transition steps become exit plan steps if the engagement is offboarded.
## The exit plan's sources
| Source | What Coverbase reads | The step |
| - | - | - |
| **Data it held** | IRQ answers about data, data processing, business associate and data sharing agreements, and the contract's data privacy terms | The vendor returns or destroys the data, evidenced by the destruction certificate. With nothing on record, an owner signs off that no data is held. |
| **Access it had** | The vendor's applications linked to an Okta or Entra application, with their assignment counts | Remove the single sign-on applications and assignments, evidenced by an export showing none remain. |
| **Integrations** | Applications with stored credentials, and API integration agreements | Disconnect each one. |
| **Contract** | Every linked contract that is not terminated | Send the termination notice within its notice period, or remove this engagement from a contract other engagements still use. |
| **Continuity** | The engagement's continuity plan | One step per transition step, plus confirming the backup suppliers can take over. |
## On the engagement tracker
An offboarding request moves the engagement's tracker to its **Exit** stage, which reads **Exit under way** until the plan closes and **Exited** with the date afterwards. See [Engagement record](/products/engagement-record#the-exit-stage).
## The contract handoff
When an assessment completes, a handoff opens on each engagement it was due diligence for that has not started yet, and Supply Chain (or the TPRM Office) gets a task to file the executed contract. Recording **Proceed to contracting** on a Risk Summary opens one too, and the TPRM Office can start one by hand. A contract signed through e-signature completes the handoff by itself. A contract signed on paper is completed by uploading the executed copy. Either way, the engagement moves to its active status and the Transaction Owner and the TPRM Office are notified.
## Routing
Offboarding approvals and the executed contract task go to two user groups set under **Configuration → Communications → Lifecycle Routing and Reminders**: the TPRM Office and Supply Chain. A task for a group follows the group's own assignment rule. With no TPRM Office group, offboarding approval falls back to the vendor's first risk analyst, then the requester. The approvals a request needs are fixed when it is filed, so changing the routing later cannot strand a request half approved.
## What it does not do
* Uploading a paper-signed copy does not mark the contract as executed in its signature workflow. Only the e-signature engines set that state. The handoff, the engagement status and the notices are the same either way.
* Canceling an offboarding does not undo what already stopped. A canceled assessment stays canceled.
## Where to go next
File a request, work the exit plan, write a continuity plan and complete a handoff.
Owner attestation, the most common way an offboarding starts.
How your own data comes back from Coverbase at the end of your contract.
Read engagements and their status from another system.
# People intelligence
Source: https://docs.coverbase.com/products/people-intelligence
A cited dossier on the people who run a vendor: executives, board, reporting lines, and what adverse-media screening found against them.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Corporate Registrations tells you the company is real. People intelligence tells you who runs it.
It answers the questions diligence asks about a counterparty's leadership. Who is accountable. How deep the bench is. Whether anyone named is carrying a sanctions listing, an enforcement action, or a live investigation. It answers them from public sources, without contacting the vendor.
The page is the **People** tab under **Vendor Intelligence**, alongside **Security**, **Financial** and **Registrations**.
## Confirmed and unconfirmed are not the same thing
This distinction shapes the whole page, so it is worth understanding first.
People research is dominated by one failure mode: namesakes. Search the leadership of a mid-sized company and you will reliably surface a better-known executive with the same name at a different firm. Presenting that person as the vendor's CFO is worse than returning nothing, because it looks like a finding.
Every name therefore lands in one of two groups.
Tied to this vendor by a source that resolved through the vendor's own domain, or by a matched professional profile. These are the only names that are counted, charted, or scored.
Surfaced in research but not tied to this vendor with confidence. Shown so you can judge them, and excluded from every count on the page.
Do not quote an unconfirmed name as the vendor's staff. It is a research lead, not a finding. The section exists so you can see what was considered and set aside, which is more useful than dropping it silently.
## What the page shows
**Coverage.** Confirmed people, executives and board currently serving, how many of those are corroborated by a registry filing, and how many were screened for news. A person named as an officer in a public filing is a stronger claim than one scraped from a leadership page, so the two are counted separately.
**Adverse media and screening.** Negative news, sanctions matches and enforcement matters tied to the people above. Each finding carries a category, a severity, an outcome, and a link to the source.
**Reporting lines.** Where published reporting relationships could be established, they are drawn as a tree. This is partial by nature. It reflects what is public, not the vendor's internal org chart.
**People.** A card per person: title, role, tenure, prior roles, other board seats, and links to the profiles that back them. Former staff are labelled rather than dropped, because a recent executive departure is often the thing you wanted to know.
## How the research runs
Screening is not a single "bad news" search. For each person, four separate queries run against news sources, covering litigation, regulatory and enforcement action, financial crime, and abrupt departures. The overlap between those corpora is small: a regulator's action rarely appears in the same results as a bankruptcy filing.
The results are then read into structured findings, with one instruction that matters more than the rest: discard anything that cannot be tied to this person at this company. Returning nothing is the correct answer for a person with no adverse coverage.
Screening is bounded and works top down. Founders and executives are screened first, then the board, then other leadership. The page records how many people were screened, and each person's card says whether they were among them.
A person who was not screened has not been cleared. Their card says so. This matters most on a large leadership team, where the tail of the list is exactly where an unscreened name could hide.
## Severity and outcome are separate
A dismissed fraud claim and a fraud conviction sit in the same category and are nowhere near the same fact.
Every finding carries both a severity (how serious the matter is) and an outcome (where it got to: alleged, under investigation, settled, concluded, dismissed, or unclear).
A finding marked **Dismissed** deducts nothing from the score. Scoring a claim the subject was cleared of would let anyone impose a lasting cost on a vendor by filing something that fails.
Findings the subject publicly contests are marked as disputed and shown with that label, so you are never handed one side of a contested matter as settled fact.
## No findings and not screened are different
If screening could not run, because a source was unreachable or the vendor has not been researched yet, the page says **Not screened**. It does not show a zero.
A zero reads as a clean record. The two mean opposite things. Everywhere this data appears, on the page, in the Zero Touch score, through the API, or to an agent over MCP, an unscreened vendor is reported as unknown.
This also governs scoring. When screening has not run, the People component of a [Zero Touch Score](/user-guides/zero-touch-assessments) deducts nothing at all, and labels itself so nobody reads the number as a clean bill of health.
## Where the data comes from
| Source | What it contributes |
| - | - |
| Org chart data | Serving staff resolved through the vendor's own domain, with titles, reporting lines and profile links |
| Web research | Leadership named on the vendor's own site and in public profiles |
| Public registers | Officers and directors named in corporate filings |
| News search | Litigation, regulatory action, financial crime and departure coverage, per person |
| Sanctions lists | OFAC SDN and consolidated screening against the confirmed names |
A sanctions match is reported at high severity, always with the caveat that name similarity is not identity. Confirm against the listing itself before acting on one.
## Using it
Reach for the page before an assessment, to see whether there is an accountable leadership team at all. A vendor with nobody on record is not disqualified, but it is a different conversation.
Turn on the People component in Zero Touch scoring when you want leadership visibility and adverse media to feed triage directly. See [Zero Touch Assessments](/user-guides/zero-touch-assessments).
Agents reach the same dossier over MCP with `query_vendors(kind="leadership", vendor_id="cbvndr_...")`. That is distinct from `kind="people"`, which returns your own team's owners and watchers on the vendor.
## Limits worth knowing
Coverage reflects what a company publishes. A private company that names nobody publicly will show little here, and that is a fact about its disclosure rather than its governance.
Reporting lines are reconstructed from published relationships and are usually incomplete.
People sharing a name are kept as separate records rather than merged. A nickname and a legal first name appear as two people. A visible duplicate is a better failure than a wrongly merged pair.
Politically exposed status is recorded as a fact calling for enhanced diligence. It is not a finding against the person.
None of this is a background check. It is open-source research, and it is where a conversation starts rather than where a judgement about an individual ends.
## Related
The screen-by-screen walkthrough.
The legal entity behind the vendor.
# Program Insights
Source: https://docs.coverbase.com/products/program-insights
Program Overview: the state of your third-party risk program on one page, with five KPIs, residual risk by business unit and risk domain, the pre-contract pipeline, six slicers, three levels, drill-downs into the matching lists, exports and distribution.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
**Program Overview** answers the questions a TPRM Office is asked every month: how many engagements are live, how much residual risk sits at the top of the scale and where, what is stuck in the pipeline before contract, and how long a request takes to reach a decision. Every figure opens the list behind it.
Your Coverbase representative turns on the third-party lifecycle features for your organization.
## What it shows
**Active Engagements** (including those with an exit under way) across how many third parties; third parties or engagements at your elevated residual risk levels (such as High or Critical), with the change this quarter; **Reviews Past SLA** out of those in flight; **Issues Past Due**, with how many block a contract; and the median **Request to Decision** time over the last 90 days.
A heat grid of the mean residual score for each business unit and risk domain, coloured by your risk levels, with how many were scored and how many sit at the elevated levels.
Requests and engagements by stage, from **Request** through **Triage**, **Inherent risk**, **Due diligence** and **Decision** to **Contract**, until they reach a signed contract. Active, exiting and exited engagements are past the pipeline.
View the program at the **Enterprise**, **Engagement** or **Third party** level, and slice it by tier, business unit, contract type, control status, geography and risk domain. The view is held in the link, so sharing the link shares the view.
Each KPI, heat grid cell and pipeline stage opens the matching vendor, engagement or finding list, filtered to what it counts.
Export the view to Excel or CSV, generate the board pack, and see on the **Distribution** card where your program's data goes: warehouse destinations, the board pack schedule and scheduled dashboard emails.
## The three levels
| Level | Each row is |
| - | - |
| **Enterprise** | A third party at its worst: per domain, the higher of its own score and any of its engagements' scores. |
| **Engagement** | A live engagement, scored on its own. |
| **Third party** | A third party, scored by its rolled-up risk profile. |
## When a list shows more than the figure
When every slicer has a field on the list a figure opens, the list is filtered the same way. Otherwise the drill names the rows by ID, up to 100; past that, the list shows a superset of what the figure counted, and the page says so before you open it.
## Drill into a business unit or an engagement
From the whole program you can drill into one business unit, which narrows every figure to it and lists its third parties or engagements as the grid's rows, and then into one engagement. At the **Third party** level, a row opens the vendor page. The drill is held in the link with the level and slicers.
## Exiting and exited engagements
An engagement with an exit under way still counts as active, because its contract runs until the exit completes. Once the exit completes, the engagement leaves every figure, the same as an engagement the Transaction Owner decided not to proceed with. A drilled engagement that is active, exiting or exited says so under the pipeline bars.
## Where to go next
Read the page, slice it, drill in and export.
The tracker the pipeline stages come from.
The destinations on the Distribution card.
Build your own charts on the same data.
# RFP Platform
Source: https://docs.coverbase.com/products/rfp-platform
A complete RFP platform purpose-built for regulated industries, with risk, compliance, security, and legal evaluation embedded into vendor selection.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
RFP Platform brings vendor selection into the same risk-aware program as the rest of Coverbase. Built for regulated industries, it embeds risk, compliance, security, and legal evaluation directly into the request-for-proposal process, so the diligence that normally happens *after* a vendor is chosen instead shapes the decision while it's still being made.
## What it does
Describe what you need in a sentence. The wizard asks the clarifying questions, drafts the RFP, proposes a timeline, researches vendors, writes the weighted rubric, and generates the questionnaire. All of it is editable before anything is created.
Compare the field before contacting anyone. Coverbase researches how each shortlisted vendor would most plausibly answer, from public information, so ten candidates become three without spending anyone's goodwill.
Every AI score cites the verbatim span of the response it rests on, sits beside the reviewer's own score rather than replacing it, and fails a must-have on ambiguity rather than passing it.
Compare bidders across weighted criteria, with year-one and three-year cost side by side and a badge for how firm each number is: a published price, a quote, an indicative range, or withheld.
After the award, a record of why: the reasoning, each runner-up and the specific reason it lost, the risks knowingly accepted, and the conditions the winner must meet before signature.
Carry the winning bidder's responses and evidence straight into intake and assessment, with no re-keying of what was already collected.
## How to integrate
Hand a selected vendor directly to intake so the engagement enters the TPRM program at the correct depth.
Reuse RFP responses and uploaded evidence as the starting point for a scoped risk assessment.
Query RFPs conversationally. "Which bidders met our encryption requirements?" or "Summarize the security scores for this RFP."
## Common workflows
Evaluate bidders on capability and cost alongside security, privacy, legal, and compliance posture in one scorecard, so a cheaper bidder with unacceptable risk doesn't win by default.
When a winner is chosen, push their RFP responses and evidence into [Autonomous Intake](/products/autonomous-intake) and [Assessment Copilot](/products/assessment-copilot) so onboarding starts from what's already known.
Run sourcing events that satisfy regulatory expectations for documented, criteria-based vendor selection, with a defensible audit trail of how each decision was made.
## Getting started
The full walkthrough: the eight wizard steps, the seven sections of an RFP, running it without outreach, scoring against the rubric, and recording the decision.
RFP Platform is configured in the dashboard. RFPs can also be drafted, queried and compared through the [MCP server](/mcp/overview), and an awarded vendor is onboarded into the same vendor record that [Autonomous Intake](/products/autonomous-intake) and [Assessment Copilot](/products/assessment-copilot) work from.
# Risk methodology
Source: https://docs.coverbase.com/products/risk-methodology
One inherent risk model for intake, every Risk Group and every report: how domain scores roll up, who reviews each domain, when overdue work escalates, which questionnaire version is live, and how manual overrides are justified and expire.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The **Risk Methodology** page under **Configuration** holds the rules your inherent risk scores follow. Intake, every Risk Group's review and every report read the same settings, so a change made here applies everywhere at once.
Your Coverbase representative turns on the third-party lifecycle features for your organization.
## What it covers
The domains an inherent risk questionnaire (IRQ) scores, the weight each carries, and the Risk Group that reviews it. With no weight on any domain, the questionnaire keeps its flat score.
How domain scores become one overall rating: a weighted average (the default), the highest domain, or a weighted average that never sits more than one tier below the worst domain.
Who reviews intake and each domain, by requesting group, business unit, tier and domain. The most specific matching rule wins.
When a work item is overdue by a set number of days, it is copied to or reassigned to a user, a group or a group's lead. Each rule escalates an item once.
Draft, publish and retire versions of an IRQ. Published and retired versions are read-only, every change is recorded in a changelog, and a content review cadence reminds the owner.
Every manual change to an inherent or residual score needs a written rationale. An override can expire after 30, 90, 180 or 365 days, with a countdown beside the score, after which the calculated score returns.
## How the score is built
1. **Domain scores.** Each scored answer contributes to the score of the domain its section belongs to.
2. **Weighting.** When at least one active domain carries a weight, the overall score is the weighted average of the domains that scored. Weights do not have to add up to 100, and a domain the questionnaire did not cover is left out rather than counted as zero. Answers in a section with no domain, or a domain with no weight, are counted and shown on the review so nothing is dropped silently.
3. **Aggregation method.** The org's method then applies. **Highest domain wins** replaces the score with the worst domain's score. **Weighted average with a domain floor** keeps the weighted score but lifts it to at least the lowest score of the tier one below the worst domain's tier, so a Critical domain makes the overall rating at least High. A domain on the lowest tier imposes no floor.
4. **Answer floors.** Last, any answer option that carries a minimum score lifts the whole questionnaire to that minimum.
The IRQ review shows **Why This Rating**: the answers that moved the score most, which domain rated it or which floor lifted it, and any answers flagged for review. The aggregation method applies to questionnaires scored after you change it; scores already recorded are not recalculated.
## Routing and escalation
When an IRQ is approved, every domain it scored gets a review task for its Risk Group. The reviewer matrix decides who: a rule can name a requesting group, a business unit, a tier and a domain, and any criterion left on **Any** matches everything. With no matching rule, the domain's own reviewers review it. Intake review is matched before a tier is known, so only rules without a tier or domain apply to it.
Escalation rules run once a day over pending work items. **Notify** gives the target their own copy of the item, which closes when the original's record resolves. **Reassign** moves the item to the target. Every escalation is recorded on the item.
## Versions
An IRQ is a family of versions. At most one is published, and new sends always use it. Publishing a draft retires the previous version for new sends, while questionnaires already out finish on the version they were sent with. Lookups that find a vendor's response, such as a portal ask, an assessment plan or a workflow condition, match on the whole family, so naming a retired version still finds a response sent on its successor.
While a version is published or retired, its questions, sections, options and conditions cannot change. The editor offers **Draft new version** instead. Its name, reviewers and applicability stay editable.
**Compare** puts two versions side by side: sections, questions, answer options, weights, risk domains and review flags, each marked added, removed or changed, with a summary of what moved. Versions can be retired in bulk: a retired draft is discarded, and a fully retired questionnaire stops being sent until a new version is published.
## What-if scoring
Two what-if views rerun the real scoring without saving anything:
* **Inherent Risk What-If**, on a submitted inherent risk questionnaire: change answers and see where each domain and the overall rating would land, through the same weights, roll-up and answer floors.
* **Residual Risk What-If**, on an assessment's summary: turn on the open issues to remediate and see how far each drops its domain's and the overall residual risk, scoring each remediated issue at its compliant level, the same rule a finding's residual credit uses. A significant deficiency floor stays in force.
## Overrides
Editing an inherent or residual score by hand opens the score editor with a required **Rationale** and an **Override Expires** choice (**Never**, or after 30, 90, 180 or 365 days). A request without a rationale is refused. When an override expires, a daily job restores the last calculated score for each risk type the override changed. If something has replaced the override in the meantime, the newer score stands. While an override is active, a countdown reads **Override ends in N days** beside the score, and the vendor's risk profile shows **Override expired** on a score that lapsed.
## Where to go next
Set weights, the aggregation method, reviewer rules, escalation and versions step by step.
The packaged inherent risk questionnaires you can start from.
The IRQ scoping rules that decide when a request needs a questionnaire.
How domain-scoped reviews and approvals work on an assessment.
# Security Intelligence
Source: https://docs.coverbase.com/products/security-intelligence
An outside-in security rating measured from the vendor's own infrastructure, with every point deducted traceable to a specific observed configuration.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Security Intelligence rates a vendor's external security posture without asking the vendor anything, without an agent, and without a questionnaire. Coverbase queries the vendor's own public infrastructure (its DNS records, its TLS certificate, the headers its web server returns) and scores what it finds.
The distinction that matters: this is **measured**, not reported. A rating built from feed subscriptions tells you what someone said about a vendor. This tells you what the vendor's systems are configured to do, today, and shows you the record it read.
This is an optional feature. Ask your Coverbase representative to turn it on for your organization.
## What it does
A domain that publishes SPF and DMARC but sets `~all` and `p=none` blocks nothing. A presence check scores it identically to a domain enforcing `-all` and `p=reject`. Coverbase parses the policy and scores what it would do to a forged message.
Each factor lists the specific findings behind its grade: what was observed, on which host or selector, and how many points it cost. Open the rationale on any factor to see the arithmetic.
A finding carries the date it was first seen. A weak DKIM key that has been open for eleven months is a different conversation than one that appeared last week.
When a probe cannot reach a conclusion, that factor is excluded from the rating rather than scored as a failure. A timeout is not evidence about the vendor.
Each finding names the step that resolves it, written for whoever operates the asset. Forwarding one hands the provider a specific change to make rather than a problem to research.
Attribution is worked out from domain names, so it is sometimes wrong in both directions. Dispute an asset that is not the vendor's and it leaves the scan and the rating. Add one the scan cannot discover and it is probed and scored like any other.
Every profile carries a ranked list of next steps, each resting on a named observation: an actively exploited CVE, a database port open to the internet, a DMARC record that does not enforce. Each one copies a question ready to send to the vendor. The list is the same on the page, in a report and through MCP.
A refresh records what it found that the previous one did not, and the reverse: findings that appeared or were resolved, factors that moved, assets that arrived or left. A returning reader learns what is new in two lines rather than by rereading the page.
## What gets measured
Four probes read the vendor's live infrastructure on each Vendor Intelligence refresh. All four are passive: they read published records and make ordinary client requests, the same way any browser or mail server would. Nothing is scanned, brute-forced, or authenticated against.
| Probe | What it reads |
| - | - |
| **Email authentication** | The SPF `all` qualifier and lookup count, DMARC `p`/`sp`/`pct` and whether reports are collected, DKIM key size across the selectors major senders publish, MTA-STS mode fetched from the well-known URL, TLS-RPT, and BIMI |
| **Web application headers** | Whether the origin upgrades to HTTPS at all, HSTS and its lifetime, Content-Security-Policy (including report-only-only and `unsafe-inline`), clickjacking cover, MIME-sniffing protection, Referrer and Permissions policies, version banners, and the security flags on every cookie set |
| **TLS certificate** | Chain trust, whether the certificate covers the hostname, days to expiry, and the protocol and cipher negotiated |
| **Lookalike domains** | Registered typo and homoglyph variants of the vendor's domain that resolve, with mail-capable ones surfaced first |
These sit alongside the feed-based factors Coverbase already scored (vulnerability exposure, network posture, IP and web reputation, and credential leaks), so the rating covers both what the vendor's infrastructure does and what public sources report about it.
## How the score works
The overall score runs 0-100 with a letter grade, computed as a weighted mean across eleven factors. Weights reflect how directly each factor bears on a compromise:
| Factor | Weight | What it covers |
| - | -: | - |
| Patching cadence | 18% | Known-exploited and high-EPSS vulnerabilities in the vendor's products |
| Network exposure | 14% | Exposed services and administrative interfaces |
| Email authentication | 12% | SPF, DMARC, DKIM, MTA-STS, measured as policy |
| TLS configuration | 10% | Certificate trust, coverage, expiry, negotiated protocol |
| Web application headers | 10% | HTTPS enforcement, HSTS, CSP, cookie flags |
| DNS health | 8% | Resolver and record hygiene |
| Leaked credentials | 8% | Credentials exposed in known breaches |
| IP reputation | 7% | Malicious activity attributed to the vendor's addresses |
| TLS assessment | 6% | The SSL Labs grade for the vendor's site, and any configuration warnings |
| Web reputation | 5% | Reputation verdicts from public sources |
| Domain squatting | 2% | Registered lookalikes that resolve |
Two deliberate constraints on that arithmetic:
If a probe times out, gets rate-limited, or the vendor's infrastructure doesn't answer, that factor drops out of the weighted mean. It is never scored as a failure. A vendor is not penalized for a query that failed on our side, and a clean-looking score is never manufactured from a request that didn't complete.
The same rule applies in the other direction. HTTPS enforcement is credited only when a plain-HTTP connection is refused. A request that merely timed out proves nothing, so it earns nothing.
Uncapped, this factor measures brand recognition rather than security. Every large brand has dozens of parked typo domains it never registered and cannot remove. Before the cap, GitHub scored 0/100 on it. The cap keeps a real signal (a mail-capable lookalike is worth knowing about) from turning into a penalty for being well known.
## Reading a finding
Every factor's rationale lists the individual findings behind its grade. Each one carries:
* **What was observed**: the actual value, such as `p=none`, `1024-bit`, or `TLSv1.0`
* **Where**: the host, DKIM selector, or cookie name it applies to
* **What it cost**: the points deducted from that factor
* **How long it has been open**: the date the finding was first seen, once it has survived a refresh
That last field is the one worth watching. A finding that persists across months has been seen by the vendor's own team too. It has stopped being an oversight and become a decision.
Opening a finding also shows the remediation step for its code, and whether the finding cost the rating points. Raise a tracked finding from it directly, or use **Generate findings** to raise them for every scored issue at once, which is the case a sweep across a wide estate creates.
Take a finding to the vendor as an observation, not an accusation: "your DMARC record is `p=none`, so mail forged from your domain still gets delivered. Is enforcement on the roadmap?" It is a verifiable fact about a public record, and it converts a security review into a specific, answerable question.
## Next steps and the change log
Two things sit between the rating and the evidence, and both are derived from the scan rather than written by a model.
**Next steps** is a fixed set of rules over the profile, ranked urgent, soon and routine. Urgent rules fire on evidence of active exploitation or an open door: a CVE in CISA's Known Exploited Vulnerabilities catalog, a CVE tied to ransomware campaigns, an administrative or database service reachable from the internet, a failing certificate. Soon rules fire on policy gaps: DMARC at `p=none`, SPF ending in `+all`, TLS 1.0 or 1.1, a certificate within three weeks of expiry, a lookalike domain that accepts mail, staff credentials in a breach within a year of the scan. Routine rules fire on what weakens the rating itself: findings open for six months or more, an estate nobody has reviewed, and a rating that rests on less than 60% of the model's weight.
The rules are evaluated when the page, a report or an MCP client reads the profile, not when the scan ran. A rule added or tightened applies to every vendor on the next read, and every vendor scanned before the rules existed gets a list without a rescan.
**Since last scan** is stored by each refresh against the profile it replaces, because the replaced profile is the only place a resolved finding can be found. It records the score and factor movement, findings that appeared or closed, CVEs that appeared or are no longer observed, and assets that arrived or left. A finding counts as resolved only if its factor was measured in both scans, and CVEs are compared only if both scans reached the vulnerability source, so a skipped credential never reads as a fix.
The same two blocks reach assessment reports as `{{intelligence::security next steps}}` and `{{intelligence::security change since last scan}}`, and the security posture section an agent reads carries them in full.
## Standing among your vendors
With at least five rated vendors, the rating shows where this vendor sits among them: the share of the other rated vendors the viewer can open that it scores at or above. Someone restricted to assigned vendors is ranked among those, never against vendors they cannot see. It is computed when the page opens, from the ratings as they stand, so a vendor archived this morning is out of the cohort this morning. Below five rated vendors it is not shown, because two vendors make one of them "top 50%".
## Compared with industry peers
Your portfolio is not the vendor's market. The **Industry Comparison** on the Security tab rates the vendor against three to seven companies that sell a competing product to the same kind of buyer, chosen for the product your organization buys from the vendor. A model picks them from a web search and the competitors already on the vendor's fact sheet, and Coverbase drops any pick that is not a company's own website, the vendor itself, or its parent.
Every peer is scanned with the same outside-in scan as your vendors, and the result is stored as shared research: an organization buying the same product from the same company sees the same peers and the same ratings. The page shows the vendor's factor scores against the industry average as a radar chart, then each company's rating with its band, and the PDF export carries both. Peers are chosen again every 90 days, and a peer's rating is refreshed once it is more than 30 days old. See [Compared with industry peers](/user-guides/security-intelligence#compared-with-industry-peers) for how to read it.
## The predictive index
Alongside the rating, Coverbase publishes a forward-looking index of exploitation likelihood. It is driven by membership in CISA's Known Exploited Vulnerabilities catalog, peak EPSS probability, known ransomware association, and how much attack surface is externally exposed.
The rating answers "how well is this vendor configured?" The predictive index answers "how likely is something to happen soon?" They can diverge, and the divergence is informative: a well-configured vendor running one product with an actively exploited CVE deserves attention that its letter grade alone won't prompt.
## What this does not tell you
A clean external profile is **not** evidence of good internal security. Everything here is visible from outside the perimeter. It says nothing about access control, key management, secure development, incident response, or how the vendor treats your data once it's inside their systems. Use it to prioritize and to interrogate, never as a substitute for an assessment.
Three more limits worth stating plainly:
* **DKIM absence is inconclusive.** DKIM has no discovery mechanism; a verifier learns the selector from a message it received. Coverbase probes the selectors major senders publish, so a domain signing with a private selector reads as unsigned. Absence is therefore scored as *unknown* with a small deduction, never as a failure.
* **The rating describes the domain we scanned.** A vendor with a well-configured marketing domain and a neglected application domain will rate on whichever one is on file. **Scan a different domain**, beside the verdict on the Security page, points the scan at another one for every organization that monitors the vendor.
* **Attribution is heuristic, and correcting it is manual.** Disputing an asset fixes one vendor's estate; it does not make the attribution better for the next vendor. Adding the assets the scan cannot discover is the same trade in the other direction, and although they go in as one list against one rescan, someone still has to know they exist.
## Where it appears
The **External Security Intelligence** card carries the score, grade, factor breakdown, and per-factor findings, refreshed on the regular Vendor Intelligence cadence. The **Security** tab opens the same data full width, with rating history, every factor expanded to its findings, the reviewable estate, and a section per evidence class.
Measured posture is supplied to control evaluations as authoritative evidence, ranked ahead of web results. A control asking about email authentication is answered from the vendor's actual DNS records rather than from a marketing page claiming compliance.
A new vendor request is scored against measured posture before the web is consulted.
Ask conversationally: "What's the security posture for Acme?" or "Which of my vendors have DMARC set to none?"
## Availability
Security Intelligence is an optional feature, enabled per organization. **Contact your Coverbase representative to have it turned on.**
Organizations without it keep the security rating exactly as it was before this feature shipped: the same seven factors at the same weights. Enabling it adds the four measured factors and re-weights accordingly, so expect ratings to move once it's on. That movement is the point: the new rating distinguishes vendors the old one scored alike.
See also [Vendor Intelligence](/products/vendor-intelligence) for corporate identity validation and the [Financial Health Score](/products/financial-health-score), both enabled alongside this feature.
# Source library
Source: https://docs.coverbase.com/products/source-library
Every data source Coverbase draws on (due-diligence blocks, continuous-monitoring feeds, and partner integrations), organized into Core, Optional, and Premium tiers.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase assembles a vendor's risk picture from three layers of intelligence: **point-in-time due-diligence blocks** queried during onboarding and periodic review, **continuous-monitoring feeds** (Supplier Radar) that surface emerging signals in real time, and **partner integrations** you can connect to deepen coverage. This page catalogs every source across all three layers.
The library spans **450+ sources**, grouped into three tiers by how you get access. Use the tabs below to filter by tier, or read the tier definitions first.
## What the tiers mean
| Tier | What it means | How you get it |
| - | - | - |
| **Core** | Live and included in the platform today, at no additional cost or setup. | Coverbase operates the connection for you: public and free-tier feeds, or Coverbase's own keys. Nothing to configure. |
| **Optional** | Coverbase has a built API connection, but the feed runs on **your** subscription. | You contract with the provider directly and supply the API keys; Coverbase plugs them in. |
| **Premium** | Available through a Coverbase paid add-on or **reseller / partner** tier. | Access is arranged through Coverbase's commercial relationship with the provider; no self-serve key required from you. |
Sources are a starting point. You can add your own feeds, pages, or APIs alongside the built-in ones, and every source's scope (and the [detectors](/products/detector-library) that read it) is configurable in the dashboard. See [Supplier Radar](/products/supplier-radar) for the continuous-monitoring product and [Radar API](/api-reference/radar) for programmatic access.
Live and included today. Every source below is operated by Coverbase using public, free-tier, or Coverbase-held credentials: there is nothing for you to buy or configure.
### Cybersecurity news & advisories
| Source | What it covers |
| - | - |
| BleepingComputer | Cybersecurity, technology, and ransomware news |
| CISA Cybersecurity Advisories | Official alerts and advisories from the U.S. Cybersecurity and Infrastructure Security Agency |
| Cybersecurity Dive | In-depth news and analysis on breaches, vulnerabilities, and threats |
| SecurityWeek | Cybersecurity news, insights, and expert analysis for security professionals |
| Dark Reading | Widely-read cybersecurity community covering news, vulnerabilities, and threats |
| Dark Web Informer | Dark-web and cybercrime aggregator tracking breaches, ransomware, and threat intelligence |
| Krebs on Security | Investigative reporting on cybercrime, data breaches, and online fraud |
| The Hacker in a Hoodie Index (SEC 8-K cyber disclosures) | Curated ledger of SEC 8-K material cyber-incident disclosures: breaches, ransomware, and unauthorized access by public companies, each linked to its source EDGAR filing |
| The Hacker in a Hoodie Index (media-reported incidents) | Curated ledger of media-reported cyber incidents beyond SEC filings, with the reporting outlet and an attribution grade |
| BSI (Germany) - Cyber security warnings | Warnings from Germany's Federal Office for Information Security on vulnerabilities and threats |
| BSI (Germany) - Press releases | Press releases from Germany's Federal Office for Information Security |
| CERT-EU - Security advisories | Security advisories from the cybersecurity service for EU institutions |
| CERT-EU - Threat intelligence | Threat intelligence reports from the cybersecurity service for EU institutions |
| CERT-FR | France's national CERT alerts and advisories on vulnerabilities and threats |
| CIS - Cybersecurity advisories | Center for Internet Security advisories on vulnerabilities in widely used software |
| Cyber Security News | News on cyber attacks, vulnerabilities, data breaches, and malware |
| CyberScoop | News on cybersecurity policy, government, and the threat landscape |
| DataBreaches.net | Independent site reporting on data breaches, leaks, and ransomware incidents |
| ENISA - Publications | EU Agency for Cybersecurity reports on the threat landscape, guidance, and good practices |
| GBHackers | Cybersecurity news on vulnerabilities, malware, and attacks |
| JPCERT/CC - Advisories | Japan's computer emergency response team's alerts and advisories |
| NCSC-NL - Security advisories | The Dutch National Cyber Security Centre's advisories on vulnerabilities in widely used software |
| NIST Cybersecurity Insights Blog | NIST's blog on cybersecurity standards, frameworks, and guidance |
| NSA - Press releases and statements | National Security Agency press releases and joint cybersecurity advisories |
| SANS Internet Storm Center | Daily handler diaries on emerging threats, scanning activity, and attacks |
| UK NCSC - Guidance | UK National Cyber Security Centre guidance for organizations on security practices |
| UK NCSC - News | News from the UK National Cyber Security Centre on threats, incidents, and advisories |
### Vulnerability, exploit & threat intelligence
| Source | What it covers |
| - | - |
| NIST National Vulnerability Database (with KEV) | NIST's CVE database enriched with CVSS scores and CPE mappings, filtered to CISA KEV-listed vulnerabilities |
| MITRE CVE Program | The foundational CVE dictionary; new CVE assignments and CNA disclosures ingested as early-warning signals |
| CISA Known Exploited Vulnerabilities (KEV) | CISA's Known Exploited Vulnerabilities catalog: CVEs with confirmed active exploitation |
| FIRST EPSS (Exploit Prediction Scoring System) | Daily EPSS exploitation-probability scores for newly published CVEs |
| GitHub Security Advisories | GitHub Advisory Database of reviewed security advisories for open-source packages and ecosystems |
| Exploit-DB | Public exploit database cataloging proof-of-concept exploit code for disclosed CVEs |
| The Hacker News | Vulnerabilities, exploits, malware, and breaches |
| The Record | Threat-intelligence journalism on ransomware, nation-state activity, and breaches |
| Outside-In Threat Intelligence | Per-vendor outside-in intelligence: discovers CVEs for a vendor's Bill of Materials and marketed products, fuses CISA KEV exploited-status and EPSS probability, and adds attack-surface signals |
| CISA Known Breach Disclosures | Breach notifications and significant cyber incidents reported to CISA under CIRCIA and related frameworks |
| AWS Security Bulletins | Amazon Web Services security bulletins on vulnerabilities and issues affecting AWS services and software |
| Chainalysis Blog | Blockchain analytics research on crypto crime, sanctions evasion, and illicit finance |
| Check Point Blog | Check Point Software's blog on threat research, attacks, and security trends |
| Check Point Research | Check Point's threat research on malware, vulnerabilities, and threat actors |
| Cisco Talos Intelligence Blog | Cisco Talos research on malware, threat actors, and vulnerabilities |
| Cloud Security Alliance - Research | Cloud Security Alliance research and guidance on cloud and AI security |
| Coveware - Ransomware blog | Ransomware incident-response insights, trends, and threat-actor reporting |
| CrowdStrike Adversary Universe | CrowdStrike's catalog of tracked threat actors, watched for new and updated adversary profiles |
| CrowdStrike Blog | CrowdStrike research on adversary activity, threat intelligence, and incident response |
| Debian Security Advisories | Debian's security advisories for vulnerabilities fixed in its packages |
| Dragos Blog | Dragos research on industrial control system and operational technology threats |
| Dragos Threat Intelligence | Dragos threat intelligence on adversary groups targeting industrial infrastructure |
| Duo Blog | Cisco Duo's blog on identity security, authentication, and access threats |
| Elastic Security Labs | Elastic's threat research on malware, intrusion sets, and detection |
| ESET WeLiveSecurity | ESET research on malware, threat actors, and security news |
| FortiGuard Outbreak Alerts | Fortinet alerts on actively exploited vulnerabilities and widespread attack campaigns |
| FortiGuard PSIRT Advisories | Fortinet's product security advisories for FortiGate, FortiOS, and its other products |
| GitHub Blog - Security | GitHub's security blog on vulnerability research and open-source supply chain security |
| GitHub Security Advisories - npm | GitHub's reviewed advisories for vulnerabilities in npm packages |
| Google Chrome Releases | Google's Chrome release notes, including security fixes and exploited-in-the-wild disclosures |
| Google Cloud Security Bulletins | Google Cloud security bulletins on vulnerabilities affecting its services |
| Google Cloud Threat Intelligence | Google Threat Intelligence Group and Mandiant research on threat actors and campaigns |
| Google Security Blog | Google's blog on security research, vulnerabilities, and protections across its products |
| JVN (Japan Vulnerability Notes) | Japan's vulnerability notes database, run by JPCERT/CC and IPA |
| Kaspersky Blog | Kaspersky's blog on threats, scams, and security research |
| Malwarebytes Labs | Malwarebytes research and news on malware, scams, and threats |
| Microsoft Security Blog | Microsoft threat intelligence and security research on threat actors, campaigns, and defenses |
| Microsoft Security Update Guide (MSRC) | Microsoft's monthly security updates and CVE details for its products |
| MITRE ATLAS | MITRE's knowledge base of adversary tactics and techniques against AI systems |
| MSRC Blog | Microsoft Security Response Center posts on vulnerabilities, incidents, and security updates |
| Okta Security Advisories | Okta's advisories for vulnerabilities in its products |
| Okta Security Blog | Okta's security research on identity threats and attack techniques |
| Oracle Security Alerts | Oracle's critical patch updates and security alerts for its products |
| Palo Alto Networks Security Advisories | Product security advisories for Palo Alto Networks firewalls, Prisma, and Cortex |
| Proofpoint Blog | Proofpoint research on email threats, phishing, and threat actors |
| Red Hat Security Blog | Red Hat's security blog on vulnerabilities, open-source supply chain, and product security |
| Securelist (Kaspersky) | Kaspersky's threat research on APT groups, malware, and vulnerabilities |
| SentinelLabs | SentinelOne's threat research on APT groups, malware, and cybercrime |
| Sophos Blog | Sophos threat research and security news on malware, ransomware, and attacks |
| Symantec Threat Intelligence | Symantec research on threat actors, campaigns, and malware |
| Tenable Blog | Tenable research and analysis of newly disclosed and exploited vulnerabilities |
| Trend Micro - Ransomware news | Trend Micro research and news on ransomware groups and attacks |
| Trend Micro Research | Trend Micro research on threats, vulnerabilities, and cybercrime |
| Ubuntu Security Notices | Canonical's notices for vulnerabilities fixed in Ubuntu packages |
| Unit 42 (Palo Alto Networks) | Palo Alto Networks' threat research on threat actors, malware, and vulnerabilities |
| Volexity Blog | Volexity research on nation-state intrusions and zero-day exploitation |
### Attack surface & exposure (outside-in)
| Source | What it covers |
| - | - |
| Certificate Transparency (crt.sh) | Subdomain and certificate discovery from public CT logs |
| Qualys SSL Labs | TLS/SSL configuration grading for a vendor's public endpoints |
| DNS & MX records (Cloudflare) | Domain and mail-exchange records for DNS and email-security posture (SPF, DKIM, DMARC) |
| Norton Safe Web | Site reputation and safety signals |
| GreyNoise | Internet background-noise context: distinguishes targeted activity from benign scanners |
| VirusTotal | File, URL, domain, and IP reputation aggregated across dozens of engines |
### Service status
| Source | What it covers |
| - | - |
| GitHub Status (components) | Per-component operational status from GitHub's status page, watched as a snapshot so a degraded component shows up as a change |
| Alpaca Markets Status | Alpaca brokerage API status-page incident history |
| Amplitude Status | Amplitude's status-page incident history |
| Atlassian Status | Atlassian's status-page incidents across Jira, Confluence, and Bitbucket |
| AWS Health Dashboard | Amazon Web Services' public dashboard of service events across regions |
| Azure Status | Microsoft Azure's public status page of active service incidents |
| Barracuda Networks Status | Barracuda Networks' status-page incident history |
| Box Status | Box's status page, watched for incidents and degraded service |
| Chargebee Status | Chargebee's status-page incident history |
| Claude Status (components) | Anthropic's status page for Claude, watched per component for incidents and degraded service |
| Cloudera Status | Cloudera's status-page incident history |
| Cloudflare Status | Cloudflare's status-page incident history |
| Confluent Cloud Status | Confluent Cloud status-page incident history |
| Cybersource Status | Cybersource (Visa) payment platform status-page incident history |
| Datadog Status - Incident history | Datadog's status-page incident history |
| Docusign Status | Docusign's status page, watched for incidents and degraded service |
| Duo Security Status | Cisco Duo's status-page incident history |
| Elastic Cloud Status | Elastic Cloud's status-page incident history |
| ERCOT - News releases | News from the Electric Reliability Council of Texas, the grid operator for most of Texas |
| Fastly Status | Fastly's status page, watched for incidents and degraded service |
| Google Cloud Status | Google Cloud's service health incidents across products and regions |
| Google Workspace Status | Google Workspace service status dashboard |
| HashiCorp Status | HashiCorp's status-page incident history |
| Mixpanel Status | Mixpanel's status-page incident history |
| New Relic Status | New Relic's status-page incident history |
| OpenAI Status | OpenAI's status-page incidents for ChatGPT and the API |
| Palo Alto Networks Cloud Status | Palo Alto Networks cloud services status-page incident history |
| PayPal Status | PayPal's status-page incidents and maintenance notices |
| Plaid Status | Plaid's status-page incident history, including bank connection issues |
| SailPoint Status | SailPoint's status-page incident history |
| Salesforce Trust | Salesforce's trust site with service status and incidents across its instances |
| Segment Status | Twilio Segment's status-page incident history |
| Slack Status | Slack's status page, watched for incidents and degraded service |
| Splunk Cloud Status | Splunk Cloud Platform status-page incident history |
| Stripe Status | Stripe's status page, watched for incidents and degraded service |
| Sumo Logic Status | Sumo Logic's status-page incident history |
| Tenable Status | Tenable's status-page incident history |
| Twilio Status | Twilio's status page, watched for incidents and degraded service |
| Zoom Status | Zoom's status page, watched for incidents and degraded service |
### Sanctions, watchlists & PEP screening
| Source | What it covers |
| - | - |
| OFAC SDN List | U.S. Treasury Specially Designated Nationals and Blocked Persons list |
| OFAC Consolidated Sanctions List | SDN list plus additional OFAC programs (sectoral, country-specific) |
| UN Security Council Consolidated List | UN sanctions list of individuals, groups, and entities |
| EU Sanctions List | EU consolidated list of persons and entities under restrictive measures |
| HM Treasury UK Sanctions List | Post-Brexit UK sanctions regime maintained by HM Treasury |
| CBP - Forced labor | CBP withhold release orders and findings against goods made with forced labor |
| DHS - UFLPA Entity List | U.S. Department of Homeland Security list of entities tied to forced labor under the Uyghur Forced Labor Prevention Act |
| EBRD - Ineligible entities | European Bank for Reconstruction and Development list of firms and individuals barred from its projects |
| Federal Register - Bureau of Industry and Security | Bureau of Industry and Security notices, including Entity List additions and export-control rules |
| GOV.UK - UK sanctions guidance | UK government guidance on sanctions regimes and how to comply with them |
| OFAC - Recent actions | Office of Foreign Assets Control announcements of new designations, removals, and sanctions guidance |
| SAM.gov - Exclusions | U.S. federal System for Award Management exclusions of debarred and suspended contractors |
| SECO - Swiss sanctions and embargoes | Switzerland's State Secretariat for Economic Affairs page on Swiss sanctions and embargo measures |
| U.S. Consolidated Screening List | The U.S. government's combined export-control and sanctions screening list from Commerce, State, and Treasury |
| U.S. Treasury - Press releases | U.S. Department of the Treasury press releases, including sanctions designations and financial policy |
| UK OFSI - Financial sanctions | UK Office of Financial Sanctions Implementation notices, guidance, and penalties |
| UK Sanctions List | The UK government's list of persons and entities designated under UK sanctions regimes |
### Regulatory & enforcement actions
| Source | What it covers |
| - | - |
| SEC Stop Orders | Orders halting share sales under a materially misleading or deficient registration statement |
| SEC Litigation Releases | Civil actions brought by the SEC in federal court |
| SEC Administrative Proceedings | Litigated administrative proceedings adjudicated by the SEC |
| SEC Reports of Investigations | Investigative reports cautioning market participants on their federal securities-law obligations |
| CFPB Enforcement Actions | CFPB actions against providers for unfair, deceptive, or abusive financial practices |
| FCC Enforcement Actions | FCC actions enforcing the Communications Act and commission rules |
| FDIC Enforcement Actions | FDIC actions against insured depository institutions and affiliated parties |
| FinCEN Enforcement Actions | FinCEN actions for AML/BSA violations |
| HIPAA Journal Breach News | Healthcare data breaches, OCR enforcement, and HIPAA-related incident reporting |
| Acas - Latest news | News from Britain's Advisory, Conciliation and Arbitration Service on workplace disputes and guidance |
| AFM (Netherlands) - News | News from the Dutch Authority for the Financial Markets on supervision and enforcement |
| AMF (France) - All news | News from France's financial markets authority on regulation and supervision |
| AMF (France) - Press releases and sanctions | Press releases and enforcement sanctions from France's financial markets authority |
| AMF (France) - Publications | Reports, guidance, and publications from France's financial markets authority |
| APRA - Media releases | Australian Prudential Regulation Authority media releases on bank and insurer supervision |
| ASIC - Media releases | Australian Securities and Investments Commission media releases on enforcement and regulation |
| Australian Federal Police - Media releases | Australian Federal Police announcements on investigations, arrests, and cybercrime |
| BaFin - Enforcement measures | Enforcement measures and sanctions imposed by Germany's Federal Financial Supervisory Authority |
| BaFin - Press releases | Press releases from Germany's Federal Financial Supervisory Authority |
| Bank of England - Prudential regulation publications | Prudential Regulation Authority rules, supervisory statements, and consultations for UK banks and insurers |
| BfDI (Germany) - Press releases | Press releases from Germany's Federal Commissioner for Data Protection and Freedom of Information |
| Bundeskartellamt - News | News from Germany's Federal Cartel Office on merger control and antitrust cases |
| Bureau of Indian Standards - News | News from India's national standards body on product standards and certification |
| California DFPI - Enforcement actions | California Department of Financial Protection and Innovation enforcement actions against financial firms |
| CFPB - Newsroom | Consumer Financial Protection Bureau news on enforcement, rules, and consumer finance |
| CFTC - Enforcement actions | Commodity Futures Trading Commission enforcement actions and settlements |
| CFTC - Enforcement press releases | Commodity Futures Trading Commission press releases on enforcement actions |
| CFTC - Press releases | Commodity Futures Trading Commission press releases on enforcement, rules, and market oversight |
| CNIL - News | News from France's data protection authority, including sanctions and privacy guidance |
| Competition Bureau Canada - News releases | News releases from Canada's competition regulator on mergers, deceptive marketing, and cartels |
| Competition Commission of India - Press releases | Press releases from India's competition regulator on merger approvals and antitrust orders |
| CSBS - Newsroom | Conference of State Bank Supervisors news on state banking and money-transmitter supervision |
| CSSF (Luxembourg) - Publications | Publications and sanctions from Luxembourg's financial sector supervisor |
| Directorate of Enforcement (India) - Press releases | Press releases from India's financial crime agency on money-laundering and foreign-exchange cases |
| DOJ Antitrust Division - Press releases | U.S. Department of Justice Antitrust Division announcements on merger challenges and cartel cases |
| ECB Banking Supervision - Press releases | Press releases from the ECB's supervisor of significant euro-area banks |
| EEOC - Newsroom | U.S. Equal Employment Opportunity Commission lawsuits, settlements, and discrimination enforcement |
| EIOPA - News | European Insurance and Occupational Pensions Authority news on insurance and pensions supervision |
| ESMA - News | European Securities and Markets Authority news on supervision, guidance, and sanctions |
| EU Competition Cases - Search | European Commission antitrust, merger, and state aid case register |
| EU Competition Policy - News | European Commission news on antitrust, merger, and state aid decisions |
| EU Digital Strategy - News | European Commission news on digital policy, including AI, data, and platform regulation |
| EU Trade - Responsible business conduct | European Commission page on responsible business conduct and supply chain due diligence in trade policy |
| EUR-Lex - Official Journal of the EU | The Official Journal of the European Union, publishing EU legislation and official acts |
| European Anti-Fraud Office (OLAF) - News | European Anti-Fraud Office news on investigations into fraud against the EU budget |
| European Banking Authority - News | European Banking Authority news on banking regulation, stress tests, and supervision |
| European Commission - Have your say | European Commission consultations and feedback calls on upcoming EU legislation |
| European Commission - News | European Commission press releases and announcements on EU policy, regulation, and enforcement |
| European Data Protection Board - News | European Data Protection Board news, opinions, and binding decisions under the GDPR |
| European Labour Authority - News | European Labour Authority news on cross-border labor enforcement and mobility |
| European Medicines Agency - News | EMA news on medicine approvals, safety reviews, and shortages in the EU |
| European Parliament - Press releases | European Parliament press releases on legislation, votes, and committee work |
| Europol - Newsroom | Europol announcements of cross-border operations against cybercrime, fraud, and organized crime |
| FBI - Press releases | Federal Bureau of Investigation announcements on investigations, arrests, and fraud and cyber cases |
| FCA - News | UK Financial Conduct Authority news, final notices, fines, and policy statements |
| FDIC - Press releases | Federal Deposit Insurance Corporation press releases on bank failures, enforcement, and policy |
| Federal Maritime Commission - News | U.S. Federal Maritime Commission news on ocean shipping enforcement and rules |
| Federal Register | The daily journal of the U.S. government, publishing proposed and final rules, notices, and executive orders |
| Federal Register - CFPB | Federal Register rules and notices from the Consumer Financial Protection Bureau |
| Federal Register - Department of Labor | Federal Register rules and notices from the U.S. Department of Labor |
| Federal Register - FDIC | Federal Register rules and notices from the Federal Deposit Insurance Corporation |
| Federal Register - Federal Reserve | Federal Register rules and notices from the Federal Reserve System |
| Federal Register - FTC | Federal Register rules and notices from the Federal Trade Commission |
| Federal Register - NLRB | Federal Register rules and notices from the National Labor Relations Board |
| Federal Register - OCC | Federal Register rules and notices from the Office of the Comptroller of the Currency |
| Federal Register - SEC | Federal Register rules and notices from the Securities and Exchange Commission |
| Federal Register - State Department | Federal Register notices from the U.S. Department of State, including sanctions and export-control actions |
| Federal Register - Treasury | Federal Register rules and notices from the U.S. Department of the Treasury, including OFAC |
| Federal Reserve - Banking and consumer regulatory policy | Federal Reserve Board announcements on banking and consumer regulation |
| Federal Reserve - Enforcement actions | Federal Reserve Board enforcement actions against banks and their affiliated parties |
| Federal Reserve OIG - Press releases | Federal Reserve and CFPB Inspector General announcements on audits and investigations |
| Financial Reporting Council (UK) - News | UK audit and accounting regulator's news on enforcement, sanctions, and audit quality |
| FinCEN - Press releases | Financial Crimes Enforcement Network press releases on AML rules, advisories, and actions |
| FINRA - Disciplinary actions | Financial Industry Regulatory Authority disciplinary actions against broker-dealers and registered representatives |
| FINRA - Regulatory notices and news | Financial Industry Regulatory Authority regulatory notices, guidance, and news |
| FTC - Privacy and security business guidance | Federal Trade Commission guidance for businesses on privacy and data security obligations |
| Garante Privacy (Italy) - News | News from Italy's data protection authority, including sanctions and decisions |
| GOV.UK - Drug and device alerts | UK Medicines and Healthcare products Regulatory Agency alerts and recalls for medicines and medical devices |
| GOV.UK - Modern slavery | UK government guidance, statements, and statistics on modern slavery |
| GOV.UK - News and communications | UK government announcements, press releases, and policy news from every department and agency |
| GOV.UK - Product safety alerts, reports and recalls | UK government product safety alerts, risk reports, and recall notices |
| Government of Canada - News | Government of Canada news releases and announcements across federal departments |
| GovInfo - New publications | U.S. Government Publishing Office feed of new official publications from Congress, federal agencies, and the courts |
| Health Canada - Recalls and safety alerts | Health Canada's open data of recalls and safety alerts for consumer products, food, drugs, and vehicles |
| ICO - Enforcement action | UK Information Commissioner's Office fines, reprimands, and enforcement notices |
| Irish Data Protection Commission - Decisions | Decisions and fines from Ireland's data protection regulator, lead EU authority for many large tech firms |
| Irish Data Protection Commission - Press releases | Press releases from Ireland's data protection regulator on inquiries and decisions |
| Japan Fair Trade Commission - Press releases | Press releases from Japan's competition regulator on antitrust and merger cases |
| Justice Laws Website (Canada) - Acts | Canada's consolidated federal acts, watched for amendments and new legislation |
| legislation.gov.uk - UK statutory instruments | Newly made UK statutory instruments, the secondary legislation that implements Acts of Parliament |
| MAS - Enforcement | Monetary Authority of Singapore enforcement overview and actions |
| MAS - News and publications | Monetary Authority of Singapore news on monetary policy, regulation, and supervision |
| NERC - Newsroom | North American Electric Reliability Corporation news on grid reliability, standards, and enforcement |
| NERC - Reliability standards | North American Electric Reliability Corporation's reliability standards, watched for changes |
| NHTSA - Vehicle safety recalls | U.S. National Highway Traffic Safety Administration vehicle and equipment recalls |
| NIST - News | NIST news on standards, measurement, cybersecurity, and AI |
| NLRB - News | National Labor Relations Board news on unfair labor practice cases and decisions |
| OAIC - Notifiable data breaches | Australia's privacy regulator's notifiable data breach reports and statistics |
| OCC - Enforcement actions | Office of the Comptroller of the Currency enforcement actions against national banks and affiliated parties |
| OCC - News releases | Office of the Comptroller of the Currency news on national bank supervision, enforcement, and policy |
| Office of the Privacy Commissioner of Canada - News | News from Canada's federal privacy regulator on investigations and guidance |
| Office of the Privacy Commissioner of Canada - PIPEDA findings | Findings from Canada's federal privacy regulator under PIPEDA, including breach investigations |
| openFDA - Drug enforcement reports | U.S. Food and Drug Administration drug recall enforcement reports, via the openFDA API |
| openFDA - Food enforcement reports | U.S. Food and Drug Administration food recall enforcement reports, via the openFDA API |
| OSFI - News | Canada's Office of the Superintendent of Financial Institutions news on supervision and guidelines |
| OSHA - News releases | U.S. Occupational Safety and Health Administration citations, penalties, and workplace safety news |
| PDPC Singapore - Commission decisions | Enforcement decisions from Singapore's Personal Data Protection Commission |
| PDPC Singapore - Press room | Press releases from Singapore's Personal Data Protection Commission |
| Reserve Bank of India - Notifications | Reserve Bank of India notifications and circulars to banks and financial institutions |
| SEBI - Updates | Orders, circulars, and enforcement updates from the Securities and Exchange Board of India |
| SEC - Press releases | U.S. Securities and Exchange Commission press releases on enforcement, rulemaking, and agency actions |
| SFC Hong Kong - Circulars | Circulars from Hong Kong's Securities and Futures Commission to licensed firms |
| SFC Hong Kong - Press releases | Press releases from Hong Kong's Securities and Futures Commission on enforcement and policy |
| Singapore Ministry of Manpower - Newsroom | Singapore Ministry of Manpower news on employment rules, enforcement, and workplace safety |
| U.S. Customs and Border Protection - Newsroom | CBP announcements on trade enforcement, seizures, and border policy |
| U.S. Department of Justice - Press releases | U.S. Department of Justice announcements of indictments, guilty pleas, settlements, and civil actions |
| U.S. Department of Labor - News releases | U.S. Department of Labor news on enforcement, wage-and-hour cases, and labor policy |
| U.S. Department of Labor ILAB - Reports | U.S. Department of Labor reports on child labor and forced labor in global supply chains |
| U.S. EPA - Enforcement | U.S. Environmental Protection Agency enforcement cases, settlements, and compliance actions |
| U.S. Small Business Administration - Newsroom | SBA announcements on loans, disaster assistance, and small business programs |
| U.S. Trustee Program - Press releases | U.S. Department of Justice announcements on bankruptcy fraud and abuse enforcement |
| UK CMA - Cases | UK Competition and Markets Authority case updates on mergers, markets, and consumer enforcement |
| UK Insolvency Service | UK government updates on insolvency statistics, director disqualifications, and investigations |
| UK Office for Product Safety and Standards | UK government updates on product safety enforcement and standards |
| UK Trade Remedies Service - Cases | UK anti-dumping, countervailing, and safeguard investigations into imported goods |
### Breach notification registries & disclosures
Official registries where a breach becomes public because the law required someone to file it. These land days to weeks before press coverage and cover every filing, not only the companies a newsroom would write about. See the [breach notification monitoring guide](/user-guides/breach-notification-monitoring) for how to use them.
| Source | What it covers |
| - | - |
| California AG - Data Breach Notifications | Every breach notice filed with the California Attorney General, with the reporting organization, the breach dates, and the notice sent to residents |
| Delaware AG - Data Security Breach Database | Filings with the Delaware Attorney General, including Delaware residents affected |
| Washington AG - Data Breach Notifications | Filings with the Washington Attorney General, with Washingtonians affected and the categories of information compromised |
| Vermont AG - Security Breach Notices | Filings with the Vermont Attorney General, with the reporting organization's sector, residents affected, and data categories |
| Oregon DOJ - Data Breach Reports | Filings with the Oregon Department of Justice, with breach, discovery, and notification dates |
| Indiana AG - Security Breach Reports | Indiana's year-to-date registers, with dates and Indiana residents affected |
| Texas AG - Data Security Breach Reports | Filings with the Texas Attorney General since September 2021, with the information affected and Texans notified |
| Hawaii OCP - Security Breach Notices | Filings with Hawaii's Office of Consumer Protection, with how the breach happened, Hawaii residents impacted, and the notification letter |
| Rhode Island AG - Data Breach Notifications | Filings with the Rhode Island Attorney General, required of any breach touching more than 500 Rhode Islanders |
| Maryland AG - Security Breach Notices | Filings with the Maryland Attorney General, with Marylanders affected, what information was breached, and how |
| Iowa AG - Security Breach Notifications | Filings with the Iowa Attorney General, with the business, its industry, and the notice sent to Iowans |
| Massachusetts AG - Data Breach Notification Reports | Filings with the Massachusetts Attorney General, with residents affected and whether the data was encrypted |
| New Hampshire DOJ - Security Breach Notifications | Filings with the New Hampshire Department of Justice, published as the notice letters themselves |
| HHS OCR - HIPAA breaches affecting 500 or more | Every HIPAA breach of 500 or more records reported to the Office for Civil Rights, in all fifty states |
| FTC - enforcement and Health Breach Notification Rule actions | Federal Trade Commission actions, including Health Breach Notification Rule enforcement |
| SEC EDGAR - 8-K Item 1.05 cyber incident disclosures | Material cybersecurity incidents disclosed by public companies on the item created for them |
| SEC EDGAR - 10-K / 10-Q cybersecurity disclosures | Annual and quarterly reports discussing a material cybersecurity incident |
Not every state publishes what it receives. New York, and most states, take filings through a portal and publish nothing back, so there is nothing to monitor. Maine took its public database offline in June 2026 after fake filings were submitted against real companies. Wisconsin never collects the data at all: its law requires notice to affected individuals only, not to any state agency. Montana's breach page no longer exists. For every other state, coverage comes from the national sources above: HHS OCR spans all fifty states for healthcare, SEC EDGAR for public companies, and the FTC for federal enforcement.
### Natural hazards
Earthquakes, storms, floods, wildfires and severe weather warnings. These feeds never name a company: Coverbase matches each hazard to the vendors whose sites fall inside its area. See the [natural hazard monitoring guide](/user-guides/natural-hazard-monitoring) for how to use them.
| Source | What it covers |
| - | - |
| USGS Earthquakes (M4.5+) | Every earthquake of magnitude 4.5 or more worldwide, with depth, PAGER alert level and tsunami flag |
| GDACS Disaster Alerts (orange and red) | UN and European Commission alerts for earthquakes, tropical cyclones, floods, volcanoes, droughts and wildfires worldwide |
| NASA EONET natural events | Open wildfires, severe storms and their tracks, volcanic eruptions, floods and landslides worldwide |
| US National Weather Service - severe and extreme alerts | US tornado, severe thunderstorm and hail, flash flood, hurricane, winter storm, extreme heat and fire weather warnings |
| Meteoalarm - Sweden weather warnings | Orange and red warnings from the Swedish national weather service |
| Meteoalarm - the Netherlands weather warnings | Orange and red warnings from the Dutch national weather service |
| Meteoalarm - Germany weather warnings | Orange and red warnings from the German national weather service |
| GDACS - Global disaster alerts | UN and European Commission alerts for earthquakes, tropical cyclones, floods, volcanoes, and droughts worldwide |
| ReliefWeb - Updates | The UN humanitarian information service's reports on disasters, crises, and emergencies worldwide |
| USGS - Significant earthquakes | The U.S. Geological Survey's feed of significant earthquakes worldwide over the past week |
### Corporate & legal registration
| Source | What it covers |
| - | - |
| SEC EDGAR | Official registration and filing data for U.S. public companies (10-K, 10-Q, 8-K, proxies) |
| GLEIF | Global LEI Foundation: Legal Entity Identifier, legal name, entity status, jurisdiction, and addresses |
| OpenCorporates | Company registrations aggregated from official registries across 140+ jurisdictions |
| Companies House (UK) | UK government registry: officer appointments, filing history, and accounts |
| State-Level Business Registries (US) | Secretary of State filings across the 50 U.S. states for entity verification and good-standing status |
| ACRA - News and announcements | Singapore's Accounting and Corporate Regulatory Authority announcements on company registration and enforcement |
| London Stock Exchange - News | Regulatory news announcements from companies listed on the London Stock Exchange |
| Ministry of Corporate Affairs (India) - News and alerts | News and alerts from India's ministry that administers company registration and the Companies Act |
| NSE India - Corporate announcements | Corporate filings and announcements from companies listed on India's National Stock Exchange |
| SEC EDGAR - 8-K Item 1.03 bankruptcy filings | U.S. public-company Form 8-K filings reporting bankruptcy or receivership under Item 1.03 |
| The Gazette - Insolvency notices | The UK's official public record of insolvency notices, including winding-up petitions and administrations |
### Company & financial intelligence
| Source | What it covers |
| - | - |
| PitchBook | Private and public company intelligence: funding rounds, investors, valuations, and M\&A history |
| Crunchbase | Startup and growth-stage profiles: funding history, investor network, and acquisitions |
| Polygon.io | Public-markets data: ticker, market cap, list date, and stock financials |
| Perplexity | LLM-assisted resolution of private-company deal data, status, and public tickers |
| Tavily | Web-search enrichment powering a vendor's generated "scanned facts" |
| SafeBase | Vendor trust-center documents and published security posture |
| TheOrg | Org-chart and leadership enrichment |
| Atlassian Trust Center | Atlassian's trust center on security, privacy, and compliance, watched for changes |
| AWS Global Infrastructure | Amazon Web Services' page of regions and availability zones, watched for footprint changes |
| Azure Global Infrastructure | Microsoft Azure's page of regions and datacenter geographies, watched for footprint changes |
| Bankruptcy Observer | Tracker of new U.S. business bankruptcy filings |
| Cloudflare Trust Hub | Cloudflare's trust hub on security, privacy, and compliance, watched for changes |
| Crunchbase News | News on startup funding, venture capital, acquisitions, and layoffs |
| Docusign Trust Center | Docusign's trust center on security, privacy, and compliance, watched for changes |
| Google Cloud Locations | Google Cloud's page of regions and zones, watched for footprint changes |
| Google Cloud Partner Directory | Google Cloud's directory of partners, watched for changes in partner listings |
| Layoffs.fyi | Tracker of layoffs at technology companies and startups, watched for new entries |
| Morningstar | Investment research and news on companies, funds, and markets |
| Notion - Releases | Notion's product release notes, watched for new features and changes |
| Okta Trust Center | Okta's trust page on service status, security, and compliance, watched for changes |
| S\&P Global Market Intelligence - News and insights | S\&P Global Market Intelligence news and research on credit, sectors, and companies |
| Troubled Company Reporter | Daily newsletter on distressed companies, bankruptcy filings, and restructurings |
| Zoom Trust Center | Zoom's trust center on security, privacy, and compliance, watched for changes |
### Financial news & markets
| Source | What it covers |
| - | - |
| Bloomberg - Markets | Market data, equities, bonds, and finance news |
| Bloomberg - Economics | Economic news, central banks, and macro analysis |
| Bloomberg - Technology | Technology news, startups, and innovation |
| SeekingAlpha | Crowdsourced financial market news, analysis, and stock-market insight |
| AP News - Financial markets | Associated Press coverage of stocks, bonds, interest rates, and market-moving corporate news |
| AP News - Financial wellness | Associated Press coverage of personal finance, consumer credit, and household economics |
| Bank for International Settlements - News | News and research from the Bank for International Settlements, the central banks' bank |
| Bank of Canada - Press releases | Bank of Canada press releases on interest rates, monetary policy, and financial stability |
| Bank of England - News | Bank of England news on monetary policy, financial stability, and banking supervision |
| Bank of England - Publications | Bank of England reports, working papers, and financial stability publications |
| Bank of Japan - Announcements | Bank of Japan announcements on monetary policy, operations, and financial system reports |
| CME Group - Press releases | CME Group press releases on derivatives markets, trading volumes, and exchange operations |
| Deutsche Bundesbank - Speeches | Speeches by Deutsche Bundesbank officials on monetary policy and financial stability |
| Deutsche Bundesbank - Topics | Deutsche Bundesbank publications on monetary policy, banking supervision, and statistics |
| Economist Intelligence Unit - Country analysis | EIU country analysis and forecasts on political, economic, and business conditions |
| European Central Bank - Press releases | ECB press releases on monetary policy, financial stability, and euro-area markets |
| European Commission - Economic forecasts | The European Commission's economic forecasts for the EU and its member states |
| Federal Reserve - All press releases | All Federal Reserve Board press releases on monetary policy, supervision, and enforcement |
| Federal Reserve - Financial Stability Report | The Federal Reserve Board's semiannual assessment of vulnerabilities in the U.S. financial system |
| Federal Reserve - Monetary policy | Federal Reserve Board monetary policy statements and announcements |
| Federal Reserve - Speeches | Speeches by Federal Reserve Board governors on the economy, policy, and regulation |
| Financial Stability Board | Financial Stability Board reports and policy recommendations on global financial stability |
| ICE - Market data | Intercontinental Exchange market data announcements for its exchanges and indices |
| Japan Exchange Group - Listing | Japan Exchange Group listing notices, including new listings, delistings, and securities under supervision |
| Japan Exchange Group - News | Japan Exchange Group news on its markets, rules, and operations |
| Liberty Street Economics (New York Fed) | Federal Reserve Bank of New York economists' analysis of the economy and financial markets |
| MarketWatch - Bonds | MarketWatch coverage of bond markets, yields, and credit |
| MarketWatch - Top stories | MarketWatch top stories on markets, companies, and personal finance |
| New York Fed - Market updates | Federal Reserve Bank of New York statements on open market operations |
| NYSE - Continued listing | NYSE continued listing standards and lists of noncompliant issuers |
| OECD - Economy | OECD economic outlooks, forecasts, and analysis |
| OECD - Newsroom | OECD news releases on economic data, policy, and country reviews |
| ONS - Release calendar | UK Office for National Statistics releases on the economy, labour market, and prices |
| OTC Markets - Market news | OTC Markets Group news on over-the-counter securities markets |
| Reserve Bank of Australia - Media releases | Reserve Bank of Australia media releases on monetary policy and financial stability |
| Reserve Bank of Australia - Speeches | Speeches by Reserve Bank of Australia officials on the economy and monetary policy |
| SGX - Newsroom | Singapore Exchange news on its markets, listings, and operations |
| Swift - News | News from Swift on the global financial messaging network, standards, and payments infrastructure |
| TechCrunch - Venture | TechCrunch coverage of venture capital, funding rounds, and investors |
| Toronto Stock Exchange - Regulatory policies | Toronto Stock Exchange regulatory policies and procedures for listed issuers |
| World Bank - News | World Bank news on development finance, country economies, and projects |
### News & reputational
| Source | What it covers |
| - | - |
| CNN | Global breaking news |
| AP News | Fast, objective global newswire coverage |
| Reuters | International news across business, finance, politics, and technology |
| Bloomberg - Politics | Political news and policy coverage with financial and regulatory implications |
| Google News Alerts | Real-time, vendor-specific news alert subscriptions |
| Google News Feed | Broad news aggregation for ongoing reputational monitoring |
| ABC News - Business | ABC News business headlines on companies, markets, and the economy |
| Access Now | Digital rights organization reporting on internet shutdowns, surveillance, and privacy |
| AI Incident Database | Public database of real-world harms and near-harms involving AI systems |
| Amnesty International | Amnesty International news and research on human rights abuses worldwide |
| AP News - Tariffs | Associated Press coverage of tariffs, trade disputes, and their effect on companies and supply chains |
| AP News - U.S. news | Associated Press national news coverage across the United States |
| AP News - World news | Associated Press international coverage of conflicts, elections, disasters, and diplomacy |
| Automotive News | Automotive industry news on manufacturers, suppliers, recalls, and dealers |
| AWS Machine Learning Blog | Amazon Web Services' blog on machine learning and generative AI services |
| Biometric Update | Industry news on biometrics, digital identity, and the privacy rules that govern them |
| Business & Human Rights Resource Centre | Non-profit tracking the human rights impacts of companies, including allegations and company responses |
| CNA - Business | Channel NewsAsia business coverage with a focus on Asian companies and markets |
| Databricks Blog | Databricks' blog on data and AI platform features and company news |
| DatacenterDynamics | Trade publication covering data center construction, outages, power, and operators worldwide |
| EU Agency for Fundamental Rights - News | EU agency news and research on fundamental rights, including data protection and AI |
| Food Safety News | News coverage of foodborne illness outbreaks, recalls, and food safety regulation |
| Fox Business | Business news on markets, companies, and economic policy |
| FreightWaves | Freight and logistics news on trucking, shipping, carriers, and supply-chain disruption |
| Geopolitical Monitor | Independent publication of geopolitical analysis and country-risk commentary |
| GitHub Blog - AI | GitHub's blog posts on AI features, Copilot, and AI-assisted development |
| Google AI Blog | Google's announcements on AI research and products |
| Google Cloud Blog | Google Cloud's blog on products, AI, security, and customer news |
| Google DeepMind - Blog | Google DeepMind's research publications and AI news |
| Healthcare Dive | Trade publication covering health systems, insurers, health technology, and healthcare policy |
| HR Dive | Trade publication covering HR, workforce, employment law, and labor trends |
| Hugging Face Blog | Hugging Face's blog on open models, datasets, and machine learning tooling |
| Human Rights Watch | Human Rights Watch reporting on human rights abuses worldwide |
| International Labour Organization - News | International Labour Organization news on labor standards, forced labor, and working conditions |
| KnowTheChain | Benchmarks of how large companies address forced labor in their supply chains |
| Meta Newsroom | Meta's company announcements on products, policy, privacy, and AI |
| News On AIR (All India Radio) | India's public broadcaster's national news on government, politics, and business |
| NHRC India - Recommendations | Recommendations and case actions from India's National Human Rights Commission |
| NVIDIA Newsroom | NVIDIA's company announcements on products, partnerships, and AI |
| OCCRP | Organized Crime and Corruption Reporting Project investigations into corruption, money laundering, and organized crime |
| OpenAI - News | OpenAI announcements on models, products, safety, and company news |
| PBS NewsHour | Headlines on U.S. and world news, politics, and the economy |
| PR Newswire - All releases | Press release wire carrying corporate announcements on earnings, deals, leadership, and products |
| PR Newswire - Business and technology | Press release wire for business and technology announcements |
| Privacy International - News | Privacy advocacy group's reporting on surveillance, data exploitation, and privacy rights |
| Responsible Business Alliance - News | News from the industry coalition on supply chain labor, environment, and ethics standards |
| Sifted | European startup and venture news on funding, layoffs, and technology companies |
| Supply Chain Management Review | Trade publication on supply chain strategy, logistics, and disruption |
| TechCrunch - Layoffs | TechCrunch coverage of layoffs at technology companies |
| TechCrunch - Startups | TechCrunch coverage of startups, funding, and founders |
| The Economic Times | Indian business daily covering companies, markets, and the economy |
| The Seattle Times - Nation & world | The Seattle Times' national and international news coverage |
| UK Independent Anti-Slavery Commissioner | News and insights from the UK's independent commissioner on modern slavery and human trafficking |
| UK Parliament - Joint Committee on Human Rights | Inquiries and reports from the UK Parliament's Joint Committee on Human Rights |
| UN Global Compact - News | News from the UN corporate sustainability initiative on human rights, labor, environment, and anti-corruption |
| UN Press - Meetings coverage | UN meetings coverage and press releases, including Security Council deliberations and resolutions |
### Legal
| Source | What it covers |
| - | - |
| Law\.com - Corporate Legal | Legal news and analysis for corporate legal departments and in-house counsel |
| Anthropic - Legal | Anthropic's terms of service, usage policies, and privacy policy, watched for changes |
| AWS Service Terms | Amazon Web Services' service-specific terms, watched for changes |
| Box - Legal | Box's terms, privacy policy, and data processing agreements, watched for changes |
| Competition Appeal Tribunal (UK) - Cases | Cases and judgments from the UK tribunal for competition appeals and collective actions |
| Court of Justice of the EU - Case law | Judgments and opinions from the Court of Justice of the European Union |
| Dropbox - Privacy policy | Dropbox's privacy policy, watched for changes |
| European Patent Office - News | European Patent Office news on patent policy, decisions, and operations |
| Federal Court of Australia - Media releases | Media releases and judgment summaries from the Federal Court of Australia |
| IP India - News updates | Updates from India's patent, design, and trademark offices |
| Microsoft Licensing Documentation | Microsoft's product licensing terms and documentation, watched for changes |
| NCLT India - Orders | Orders from India's National Company Law Tribunal, including insolvency and corporate disputes |
| OpenAI - Policies | OpenAI's terms, usage policies, and privacy policy, watched for changes |
| Oracle - Legal | Oracle's legal notices, contracts, and policies, watched for changes |
| Ping Identity - Legal | Ping Identity's legal terms and policies, watched for changes |
| Salesforce - Legal | Salesforce's legal agreements and policies, watched for changes |
| Top Class Actions | News on class action lawsuits, settlements, and investigations against companies |
| U.S. Bankruptcy Court, District of Delaware - New filings | Docket feed from the U.S. Bankruptcy Court for the District of Delaware, a leading venue for corporate Chapter 11 cases |
| U.S. Copyright Office - NewsNet | U.S. Copyright Office news on rules, studies, and copyright policy |
| U.S. Court of Appeals for the Federal Circuit - Opinions and orders | Opinions and orders from the Federal Circuit, the appeals court for patent cases |
| U.S. Courts - News | News and announcements from the Administrative Office of the U.S. Courts on the federal judiciary |
| U.S. International Trade Commission - Section 337 | Section 337 investigations into unfair import practices, mostly patent and trademark infringement |
| UK Courts and Tribunals Judiciary - Judgments | Judgments published by courts and tribunals in England and Wales |
| UK Supreme Court - News | News and judgments from the Supreme Court of the United Kingdom |
| USPTO Patent Trial and Appeal Board | News and decisions from the U.S. Patent and Trademark Office's patent appeals board |
| USPTO Trademark Trial and Appeal Board | News and decisions from the U.S. Patent and Trademark Office's trademark appeals board |
| WIPO - Press room | World Intellectual Property Organization press releases on IP treaties, filings, and policy |
| WIPO Arbitration and Mediation Center | WIPO news on domain-name disputes and intellectual property arbitration and mediation |
Coverbase has a built API connection for each source below, but it runs on **your** subscription: you contract with the provider and supply the API keys, and Coverbase plugs them into your Vendor Intelligence and monitoring.
### Business identity & financial health
| Source | What it covers |
| - | - |
| Dun & Bradstreet - Identity Resolution | Matches vendors to a D-U-N-S number and establishes a canonical, deduplicated identity |
| Dun & Bradstreet - Company Information | Firmographics: industry classification, employee count, revenue, founding date, and geography |
| Dun & Bradstreet - Hierarchy & Connections | Parent, subsidiary, and branch linkage: concentration risk and beneficial-ownership chains |
| Dun & Bradstreet - Payment Insights | PAYDEX® score and tradeline-based payment-behavior indicators |
| Dun & Bradstreet - Financial Strength Insights | Composite stability view: D\&B Rating, Credit Recommendation, Delinquency Score, and Failure Score |
| Dun & Bradstreet - Higher-Tier Blocks | Deeper entitlements: Payment/Financial Strength Levels 2-3 and Global Failure Score, added to your D\&B connection |
### Attack surface & exposure (subscription)
| Source | What it covers |
| - | - |
| Shodan | Internet-exposed services, open ports, and banners across a vendor's attack surface |
| Censys | Internet-wide host and certificate scanning for exposure discovery |
| Have I Been Pwned | Vendor domain and credential exposure across known breach corpora |
Available through a Coverbase paid add-on or reseller / partner tier. Coverbase arranges access through its relationship with the provider: you don't supply your own key.
### Business identity, credit & verification
| Source | What it covers |
| - | - |
| Equifax - Business Verification (KYB) | Real-time Know Your Business verification with a fraud-potential index, OFAC screening, and adverse events |
| Equifax - Business Credit Reports & Risk Scores | Commercial credit intelligence, OneScore for Commercial, and business-failure/delinquency risk scores |
| Equifax - Commercial Financial Network (CFN) | Shared commercial data exchange combining payment performance with identity and firmographics |
| Equifax - Commercial Merchant Data | Near-real-time business activity from millions of merchant records to confirm a vendor is active and operating |
| Equifax - Identity Proofing / Kount 360 | Orchestrated identity and fraud platform for verifying vendor principals and beneficial owners |
### Sanctions, PEP & adverse media screening
| Source | What it covers |
| - | - |
| Equifax - Watchlist & Adverse Media Screening | 150+ sanctions and watchlists plus 30,000+ adverse-media sources via the Intelligent Match Engine |
| Equifax - AML Connect | Cloud-hosted AML screening across global watchlists, PEPs, and adverse media with ongoing monitoring |
| LexisNexis WorldCompliance | PEP, sanctions, adverse-media, and regulatory watchlist screening for BSA/AML programs |
| Refinitiv World-Check (LSEG) | Global KYC/AML due-diligence database covering PEPs, sanctions, state-owned enterprises, and adverse media |
### Financial health ratings
| Source | What it covers |
| - | - |
| Rapid Ratings | Financial Health Rating (FHR) scores and underlying performance metrics, distinct from credit ratings |
### Breach & leak intelligence
| Source | What it covers |
| - | - |
| IntelligenceX | Aggregated leaked datasets, breached databases, and dark-web intelligence for early exposure detection |
### Security ratings & outside-in monitoring
| Source | What it covers |
| - | - |
| BitSight | Continuous outside-in security ratings based on observed internet-facing behavior |
| SecurityScorecard | Continuous security-posture scoring across network, DNS, patching, and endpoint categories |
| Black Kite | Technical, financial, and compliance cyber-risk ratings for third parties |
| RiskRecon (Mastercard) | Automated third-party cyber-risk monitoring with asset discovery and remediation tracking |
| UpGuard | Outside-in monitoring for data-leak detection, typosquatting, and attack-surface management |
| Recorded Future | Real-time threat intelligence across the open, deep, and dark web |
| Mandiant | Threat intelligence and breach analytics from frontline incident response |
| Panorays | Automated third-party attack-surface assessment and security ratings |
| CyberGRX (ProcessUnity) | Exchange-based third-party cyber-risk assessments and analytics |
| Axio | Cyber-risk quantification and posture benchmarking |
| IONIX | Attack-surface discovery and exposure management across a vendor's connected assets |
### ESG & sustainability ratings
| Source | What it covers |
| - | - |
| EcoVadis | Sustainability ratings across environment, labor, ethics, and sustainable procurement |
| Sustainalytics | ESG risk ratings measuring exposure to material sustainability risks |
| ISS ESG | Corporate ESG ratings, controversy screening, and governance signals |
| CyberVadis | Third-party cybersecurity ratings built on a standardized assessment methodology |
### Legal (subscription)
| Source | What it covers |
| - | - |
| Law360 | Subscription legal news and analysis across practice areas and litigation |
## Related
The companion library of built-in detector templates that read these sources and flag matching events.
The full catalog of external systems Coverbase connects with, including GRC, procurement, and contract platforms.
The product overview: signal ingestion, enrichment, triage, and workflow orchestration.
Create radar events, and list, retrieve, and dismiss radar alerts programmatically.
# Supplier Radar
Source: https://docs.coverbase.com/products/supplier-radar
Continuous monitoring, triage, and response across your third-party ecosystem.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Supplier Radar watches threat intelligence feeds, public disclosures, sanctions and watchlists, breach databases, regulatory actions, and other external sources for events that touch your vendors. Every event your organization is exposed to becomes a **signal**, with a status, a severity, and a summary written for your portfolio, which you triage into a case, a finding, or a reassessment.
## What it does
Combine threat intel, breach databases, sanctions and watchlists, regulatory actions, and public disclosures into one event stream. See the [source library](/products/source-library) for every built-in source.
Normalize raw events and enrich them with the vendor's risk tier, services in scope, contract status, and owner so triage decisions have context.
Route signals into downstream actions: notify a vendor owner, open a finding, trigger a reassessment, or escalate to incident response.
## Key concepts
Four terms, in the order you meet them.
| Term | What it is | Where you see it |
| - | - | - |
| **Signal** | How Radar tracks an event's impact on your organization. When a new event arrives, Radar runs your detectors against it to judge the nature and severity of the impact and which of your vendors are exposed, then opens one signal with a title and summary written for your portfolio. A signal's severity is the highest severity any detector assigned to the underlying event. | The **Signals** tab, where you see newly arriving signals and the ones you have already triaged. |
| **Detector** | What decides whether an event matters to you. Each detector reads plain-language guidance, a severity threshold, category filters, and the sources it watches. When one fires, it records a verdict on each exposed vendor: severity, confidence, and reasoning. | The **Detectors** tab on a signal page shows which fired and why. Configured under **Configuration → Radar**. |
| **Case** | An investigation you open from a signal when it needs vendor outreach or a decision trail. | The **Cases** tab. |
| **Finding** | A confirmed problem on a vendor, with an owner and a due date. Create one from a signal once you know the vendor is affected, or one per exposed vendor in bulk. Creating a finding moves the signal to Triaged. | The **Findings** page, and on the vendor. Findings have their own product: see [Findings Manager](/products/findings-manager). |
### Signal statuses
Signals move through statuses as you work them. Dismiss one, acknowledge it, or open a case, a finding, or a reassessment from it, and the status follows.
| Status | Meaning |
| - | - |
| **Tracked** | A vendor you depend on is linked to the event, but no detector has alerted. The signal exists so you can see the exposure before anyone has decided it matters. |
| **Open** | No detector is alerting, but someone in your organization has handled the signal by hand: created it, edited it, or restored it after a dismissal. |
| **In alert** | At least one detector has fired on the event and stands by its verdict. This is the queue. |
| **Triaged** | You acknowledged the signal, or created a case or finding from it. |
| **Dismissed** | You dismissed the signal. Dismissing also teaches the detectors that fired to stay quiet on events like it. |
| **Closed** | A terminal status you set by hand from the signal page. Nothing moves a signal here on its own. |
The **In Alert** view shows signals that are in alert. **Triaged** shows what has already been acted on.
### Titles and summaries
Radar writes each signal's title and summary specifically for your organization, based on the event. The summary says what happened, when it occurred and when you were alerted, and which of your vendors are affected and how. It is regenerated when the detectors that fired change.
You can edit either by hand. **Regenerate summary** rewrites both from what the detectors currently report and replaces any hand edit. **Custom AI instructions** on the summary card apply to every generated summary in your organization: lead with regulatory exposure, name the contract owner, keep to two sentences.
### Exposure beyond the vendors named
An event names the vendors it is about. Radar also links the vendors that depend on them, through fourth-party relationships extracted from SOC 2 reports and subprocessor lists. A vendor whose uploaded SBOM lists an affected component is linked directly; see [Bills of materials](/user-guides/bill-of-materials#how-radar-uses-a-bill-of-materials). A breach at an identity provider becomes a Tracked signal for every vendor of yours that runs on it, before any detector has fired. The **Vendors** card on a signal page lists the vendors of yours linked to it.
## Risk propagation
A signal arriving changes nothing on a vendor. Radar moves residual risk only when you act on the signal, and only for detectors you have told to.
**What moves it.** Four actions: acknowledging the signal, creating a finding from it, starting a reassessment from it, and finalizing a case opened from it. Acknowledging is for the exposure that needs no case or finding but should still count against the vendor. Dismissing a signal leaves risk where it was.
**How far it moves.** Each detector carries a risk impact setting, off by default, with a minimum and maximum number of points out of 100 (1 to 10 unless you change them). When you act on one of its verdicts, Radar judges how severe the event is for that particular vendor and picks a value inside the range. The points land on the vendor's overall residual risk (when the detector's **Affect overall residual risk** is on) and on each risk domain the detector maps to. Inherent risk never moves. A verdict counts once, however many actions follow it.
**You see it before you are done.** After the action, **Review vendor risk profile updates** shows each affected vendor's residual risk, overall and per domain, as it now stands. Adjust any score or level and add a note, then **Save and continue**, or **Continue** to accept. Vendors on a case whose detectors do not update risk are called out and left unchanged. Organizations that do not track residual risk skip this step.
**Where you see it.** The vendor's risk profile shows the new residual score, and its risk history records the change and the detector behind it. Vendors reached through a fourth-party relationship are treated the same way: act on their part of the signal and their residual risk moves too.
## How to integrate
Create radar events, and list, retrieve, and dismiss radar alerts programmatically. Signals are not addressable through the API yet.
Turn a radar event or alert into a batch of vendor reassessments: curate, confirm, and run, without opening a case.
Subscribe to `RadarEvent.*`, `RadarDetectorResult.*`, and `Reassessment.*` events and react in real time.
Query radar alerts conversationally. "Any new radar alerts on tier-1 vendors in the past 24 hours?" or "Show me every vendor affected by the Northwind outage."
Pull radar events and findings into your SIEM, incident response platform, or executive dashboards.
## Common workflows
When a vendor is implicated in a breach disclosure, Radar surfaces every customer-side service that depends on that vendor, calculates blast radius, and routes incident notifications to the right owners automatically. No waiting for vendor self-disclosure.
Track regulatory actions, fines, and consent orders against vendors. Trigger reassessment workflows or contract review when a vendor's regulatory standing changes materially.
During industry-wide events (a major cloud outage, a widespread CVE, a sanctions enforcement action), Radar identifies every vendor in your portfolio with exposure and routes coordinated response across owners.
Detectors, sources, and default reviewers are configured in the dashboard under **Configuration → Radar**. Browse the built-in [source library](/products/source-library) and [detector library](/products/detector-library) to see what ships out of the box.
## Related
The analyst walkthrough: the In Alert view, reading a signal, and turning it into a case, finding, or reassessment.
The admin walkthrough: sources, detectors, and the tuning that keeps the queue quiet.
Every out-of-the-box detector template, by segment, with its default severity.
Events and alerts over REST, and how they map to what the dashboard shows.
# Vendor Intelligence
Source: https://docs.coverbase.com/products/vendor-intelligence
Validated corporate identity for every vendor: the legal entity, its standing, and its identifiers, from registries of record, with a citation on every fact.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Vendor Intelligence answers two questions about a company without asking the company anything: **is this corporation real and in good standing**, and **is it financially sound enough to depend on**. This page covers the first: the validated corporate identity every other answer is computed against. The second is the [Financial Health Score](/products/financial-health-score).
Both are assembled from registries of record and regulatory filings, and every figure on screen names the source it came from.
This is an optional feature. Ask your Coverbase representative to turn it on for your organization. It pairs with the [Financial Health Score](/products/financial-health-score) and [Security Intelligence](/products/security-intelligence), which are turned on the same way.
## What it does
Confirms the legal entity behind a vendor against GLEIF, OpenCorporates, and SEC EDGAR: official registered name, status, jurisdiction, incorporation date, addresses, and identifiers (LEI, DUNS, company number, SEC CIK).
A 0-100 score with five risk bands and a directional trend, computed from filed financial statements where they exist and from funding, headcount, and corporate-standing signals where they do not.
A short or ambiguous name binds only when two independent registers agree on the same legal entity. Agreement between registers outranks a few points of name similarity.
Each register is named with the identifier it matched on and a link to the record. A reviewer can verify a claim at its source instead of taking the platform's word for it.
## Corporate registration
Coverbase searches each register by company name, scores every candidate against the vendor's name, and binds a record only on a high-confidence match. A short or ambiguous name (for example, "Meta") binds only when two independent registers agree on the same legal entity.
When nothing matches confidently, the card shows **Needs review** rather than quietly picking the closest hit. That distinction matters: binding the wrong "Acme Holdings" is worse than returning nothing.
The **Licenses** tab searches the state, national and foreign registers that license the vendor's lines of business under the names this match settles; see [License and accreditation](/products/license-and-accreditation) for the method and the registers it reads.
| Source | What it establishes |
| - | - |
| **GLEIF** | Authoritative legal name, LEI, entity and registration status, jurisdiction, legal and headquarters addresses |
| **OpenCorporates** | Company number, jurisdiction, incorporation date, current status, link to the source registry |
| **SEC EDGAR** | US public-company validation: CIK, ticker, state of incorporation, SIC industry |
| **Dun & Bradstreet** | DUNS number, where your organization has its own D\&B entitlement |
## Financial Health Score
The other half of the answer lives on its own page. The **Coverbase Financial Health Score** is a 0-100 view of whether a vendor is financially sound enough to depend on, computed from filed statements where they exist and from funding, headcount, and corporate-standing signals where they do not, always labelled with which.
It depends on the corporate identity established above: the score is computed against the legal entity the registers bound, which is why a missed match shows up as a thinner score rather than a wrong one.
Confidence tiers, the five pillars and how their weights shift by tier, peer-relative ratio scoring, the caps and floors that override a weighted result, adverse events, and an honest account of coverage and limits.
## Where it appears
The **Corporate Registration** card sits in the identity column of a vendor's Vendor Intelligence section, refreshed on the regular cadence. The **Registrations** tab shows the legal entity, the evidence behind it, its corporate group, every register consulted, and **Correct with AI**.
Registry facts are supplied to control evaluations as authoritative evidence, ranked ahead of every web result. See [how evidence is sourced](#how-evidence-is-sourced).
Autofill and inherent-risk scoring consult the registers before searching the web, so a new vendor request is scored against its registered identity.
Ask conversationally: "What's the financial health score for Acme?" or "Is Acme a real registered company?"
## How evidence is sourced
A common assumption is that "web search" means handing a query to a search engine and reading the top results. That is not how Coverbase gathers evidence.
For any question about a company's identity, GLEIF, OpenCorporates, and SEC EDGAR are queried before any web crawl. Those facts enter as authoritative evidence in the prioritized bucket, ahead of every web result.
Where a registry and a web page disagree on a corporate fact, the model is instructed that the registry is correct. A register states a company's legal name and status as a matter of record; a search engine states whatever ranked well today.
Every candidate is classified for relevance to the specific control being evaluated **and** for publisher accountability: authoritative, reputable, or unreliable. Anything below the control set's minimum credibility is discarded, not merely ranked lower.
A control set configured to require authoritative sources will not cite a blog post. It will report that it found nothing, which is the correct answer.
## Availability
Vendor Intelligence is an optional feature, enabled per organization. **Contact your Coverbase representative to have it turned on.**
Corporate registration validation is populated for every organization on each Vendor Intelligence refresh. What requires enabling is the presentation of it (the Corporate Registration card leading the identity column, the registry-verification chip, and the shared citation strip) along with registry-first retrieval. Nothing about an existing Vendor Intelligence record changes until they are on.
Coverage is honest about its edges. OpenCorporates coverage varies by jurisdiction, SEC EDGAR only covers US registrants, and a DUNS number requires your own entitlement with that provider. In every case the card names which sources were consulted and which were unavailable, rather than presenting a thinner answer as a complete one.
# Warehouse data share
Source: https://docs.coverbase.com/products/warehouse-data-share
Push your third-party risk tables to your own Snowflake account, Amazon S3 bucket or BigQuery dataset on a schedule, so Power BI, Tableau or your data lake read them without going through the API.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Your Coverbase representative turns on the third-party lifecycle features, including data share, for your organization.
Data share writes the tables behind your third-party risk program into storage you own, on a schedule. Your BI team models against stable tables and views in their own warehouse instead of paging through an API, and nothing has to be exported by hand.
## What it does
Snowflake (key-pair authentication through the SQL API), BigQuery (a service account key), and Amazon S3 (a role in your account that Coverbase assumes, with no stored secret).
Each sync appends the rows that changed since the last successful one, stamped with when they were written. A failed sync is retried from the same point by the next.
In Snowflake and BigQuery, each table has a `_current` view that keeps the newest version of each row. Point your BI model at the views.
Eighteen tables, from third parties, engagements and per-domain scores to findings, risk acceptances, contracts, obligations, monitoring and Radar. Columns are added over time but never renamed or removed in place.
## Schedule
Each destination syncs **Hourly** or **Daily**, and on demand with **Sync now**. A **Sync now** that lands while a scheduled sync of the same destination is running is dropped rather than run twice.
## What lands where
* **Snowflake and BigQuery:** one table per contract table, created on the first sync. A column the contract adds later is added to the table. Beside each table, a `
_current` view keeps the latest version of each row.
* **Amazon S3:** files in gzip CSV, gzip JSON Lines or snappy Parquet at `/
/synced_date=YYYY-MM-DD/-.`, with each table's contract at `/_contract/
.json`. Deduplicate on `id`, keeping the latest `_cb_synced_at`, the same way the views do.
Timestamps are UTC. Archived records stay in the share with `is_archived` set. A hard delete is not sent, except that the `services` table is a full snapshot on every run, so a deleted service drops out of its current view.
## Credentials
A destination's credential is write-only. It is stored in a secrets manager the moment you submit it, and the page shows only a non-secret hint: the key's fingerprint for Snowflake, or the service account email for BigQuery. Archiving a destination deletes its credential. Amazon S3 stores no secret at all. Coverbase assumes your role with an external ID generated for that one destination. See [Integration credentials and signing](/security/integration-credentials#customer-s3-roles-and-external-ids).
## Where it shows
The **Distribution** card on [Program Overview](/user-guides/program-insights), under **Dashboards**, lists each destination with its status and last sync, beside the board pack and your scheduled dashboard emails.
## Where to go next
Add a destination, test it, read the run log and the table contract.
Key-pair setup and the grants the Snowflake user needs.
The role, its trust policy and the external ID.
The service account and its roles.
# Zero Touch Assessments
Source: https://docs.coverbase.com/products/zero-touch-assessments
A triage assessment assembled entirely from open-source research, with no vendor outreach.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Most vendor programs have more vendors than review capacity. The usual result is that the long tail goes unassessed, and nobody knows which of those vendors deserved attention.
A Zero Touch Assessment is a triage run for that tail. It evaluates a vendor against a fixed set of controls using open-source research, produces a single 0 to 100 score, and never contacts the vendor. Run it across a whole portfolio and rank what comes back.
## What it is, mechanically
It is an ordinary assessment on the ordinary pipeline, with the same controls, issues and evidence as any other run. Three things differ.
The control scope is fixed per organization. Seven templates ship with the product: a comprehensive default, lighter and industry-specific variants, and one for open-source software. Your organization runs one at a time, so every run evaluates the same questions and the results stay comparable. Each run records which template it used.
There is no outreach. No document request, no questionnaire, no portal. The evidence is web research, public registers, the vendor's own infrastructure, and any documents already on file.
Nothing is assigned. A run needs no reviewer, no follow-up and no vendor reply, so a batch can be launched and left to finish.
## It answers "what is this vendor?" first
The common case is knowing a vendor is in use without knowing what it does. Every run opens with the company itself: what it sells, its industry, what it would typically be used for, its services and headquarters, all researched from public sources rather than asked.
Alongside it sits a **risk tier**: a triage read of how much exposure the vendor typically creates, from critical to minimal, with the reasoning behind it. The tier is its own scale, not your organization's risk levels, because those are calibrated against a completed questionnaire and this is judged from the outside. It leaves your vendor risk scores alone unless you explicitly turn that on.
Identity confidence and risk-tier confidence are reported separately. A run can be certain which company it profiled and still be unsure how exposed that company makes you.
## It gathers the reputational picture into one section
The evidence a reputational read needs arrives from three unrelated places: adverse
media on the vendor's leadership, open watchlist matches where an organization
screens, and the reputation controls the run evaluates itself. Every run pulls all
three into a **Reputation** section and files what they found under five
dimensions: media and customer sentiment, litigation exposure, regulatory and
enforcement, executive conduct and stability, and sanctions and association.
Each dimension reports its own standing, and the section reports the standing of the
worst of them. Findings are ordered material first, so the row that matters is at the
top. A matter the subject was cleared of is still listed, because it is part of the
record of what the run read, but it is not counted as material and it does not deduct.
### Not screened is never reported as clear
A dimension nothing searched reads **not screened**, never **clear**. The two look
similar on a page and mean opposite things, so the section names every unscreened
dimension rather than leaving a short findings list to imply a clean vendor. A
dimension goes unscreened when the template carries no control for it, the vendor has
no leadership dossier yet, or the organization does not screen the relevant watchlist
feed.
The section comes straight after the vendor identity and the risk tier reasoning, in
the app and in the PDF, and the spreadsheet gives it the second tab and repeats its
read on the summary sheet under the score.
## The score
The composite combines up to five independently sourced components.
| Component | What it measures |
| - | - |
| Control evaluation | The Zero Touch control sets, scored against open-source research |
| Financial health | The vendor's [Financial Health Score](/products/financial-health-score) |
| Security | The outside-in [security rating](/products/security-intelligence) |
| Corporate registration | Whether a standing legal entity was [matched in a public register](/products/corporate-registrations) |
| People intelligence | Leadership on record, less what [adverse-media screening](/products/people-intelligence) found |
Each is scored 0 to 100 on its own, then weighted into one number carried on your organization's own risk scale.
License controls (ZT-LIC) are graded from the vendor's stored license records, found by the lookup described in [License and accreditation](/products/license-and-accreditation).
### A missing component is excluded, never zeroed
This is the rule that governs everything else.
A vendor with no filed financials has not failed the financial component. It has no financial component. The weights renormalise across whatever did resolve, so the composite never manufactures a low score out of an absent input.
The consequence is that a vendor scored on one component is not comparable to a vendor scored on three. The result carries both the weight a component was configured with and the share it carried, so you can see which you are looking at.
The same principle governs the people component. When adverse-media screening did not run, nothing is deducted, because a screening that never happened cannot establish a clean record.
## What you can do with a result
Approve it, escalate it to a full assessment, revise it from analyst notes or vendor evidence, or correct what the run was built on.
That last one exists because open-source research binds the wrong website or a similarly named company often enough to need a first-class fix. You describe the correction in plain language, the run is re-scored against the corrected inputs, and your words plus the resulting field changes are written to an append-only audit trail.
The trail cannot be edited or deleted, by anyone. A Zero Touch score can be written onto a vendor's real risk score, so the record of who changed the inputs behind it has to be one nobody can rewrite.
## Where the score goes
By default it stays on the run. You can configure it to write onto the vendor's inherent or residual risk score, or onto each service the run covered.
Only the axis you choose is written, so a Zero Touch run can never overwrite an inherent score your team set deliberately from an intake questionnaire.
## What it is not
It is not assurance. A run has never spoken to the vendor, so it cannot confirm a control is operating. It can only tell you whether public evidence supports it.
Anything you need to show an auditor needs a full assessment. Zero Touch tells you which vendors those are.
## Related
The screen-by-screen walkthrough.
Launch, rank, re-score and read the audit trail.
# Authentication
Source: https://docs.coverbase.com/quickstart
All Coverbase API requests are authenticated with a bearer token over HTTPS.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
The Coverbase API uses bearer token authentication. Every request must include a credential in the `Authorization` header. For the full set of cross-cutting rules (IDs, timestamps, idempotency, error envelope) see [API conventions](/conventions).
API keys grant significant access to your TPRM data. Never share them in public repositories, client-side code, screenshots, or support tickets. Treat them like passwords.
## Request an API key
An admin in your organization creates API keys on the **API keys** page (**Configuration**, under **Developers and integrations**) or through the [API Keys API](/api-reference/api-keys). Each key looks like `ak_...`, is scoped to a single organization, and authenticates as a service account. All data it can read or write is implicitly scoped to that org. Ask your admin for one.
A logged-in user JWT (the dashboard session token) is also accepted, which is convenient for first-party scripts running as a user.
By default a key carries no elevated permissions and can only call ordinary `/v1/*` routes. An admin can also mint a key with **admin scopes**: `keys:manage` (manage `ak_*` keys), `audit:read` (read the system audit log), `banking:read` (read full supplier bank and tax identifiers), and `review:sensitive_changes` (write bank details without waiting for review). The admin-JWT path still works for the key and audit-log endpoints. See [API key scopes](/conventions#api-key-scopes) and the [API Keys reference](/api-reference/api-keys).
## Base URLs
| Environment | Base URL |
| - | - |
| Production | `https://api.coverbase.app` |
See [API conventions → Base URLs](/conventions#base-urls).
## Authorization header
Include your key as a bearer token in every request:
```text theme={null}
Authorization: Bearer ak_...
```
## Test your connection
Use the `/v1/utils/authtest` endpoint to verify three things at once: your key is valid, you can reach Coverbase's servers, and your firewall or proxy allows outbound HTTPS traffic.
```bash cURL theme={null}
curl -H "Authorization: Bearer ak_live_xxx" \
https://api.coverbase.app/v1/utils/authtest
```
```python Python theme={null}
import os
import requests
API_KEY = os.environ["COVERBASE_API_KEY"]
BASE_URL = "https://api.coverbase.app"
response = requests.get(
f"{BASE_URL}/v1/utils/authtest",
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=30,
)
response.raise_for_status()
print(response.json())
```
A successful request returns `200 OK`:
```json theme={null}
{ "msg": "Auth successful" }
```
## Common errors
Your credential is malformed, expired, or revoked (`Invalid or expired API key.` for an `ak_` key), or its role is not permitted on the endpoint (`Unauthorized role.`). Confirm the key is active and that the endpoint accepts API keys.
A request with no `Authorization` header, or with a scheme other than `Bearer`, returns `403` with `Not authenticated`. Otherwise your credential is valid but not authorized for what it tried to do: most often an `ak_*` key calling an admin endpoint without the required scope (`insufficient_scope`), or a non-admin caller trying to grant scopes when creating a key (`scope_grant_forbidden`). A configured [API IP allowlist](/conventions#api-ip-allowlist) can also return `403 ip_not_allowed`. See [API key scopes](/conventions#api-key-scopes).
The resource does not exist, or it belongs to a different organization than your API key. All data is org-scoped to the key.
Check your VPN, proxy, and firewall rules. Coverbase requires outbound HTTPS access to `api.coverbase.app`.
Unauthenticated requests are rejected. There is no public unauthenticated surface area on the API.
# Custom Word report templates
Source: https://docs.coverbase.com/reporting/assessment-report-templates
Build a .docx assessment report template: placeholder syntax, AI-written sections, repeating findings tables, signature anchors, and the rules that govern substitution.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
A report template is an ordinary Word document that contains **placeholders**. When you export an assessment against the template, Coverbase copies the document, replaces each placeholder with live data, and returns a finished `.docx` with your formatting intact.
For the complete list of what you can put between the braces, see the [placeholder reference](/reporting/template-placeholders).
## Uploading a template
An admin turns on the **Assessment report templates** toggle in **Configuration > Assessment Settings > Reports**. The upload panel appears directly below the toggle. Until this is on, the Word export option does not appear on assessments.
Write your report in Word exactly as you want it to look. Put placeholders wherever data should appear. For a working example, click **Download Example** in the upload dialog. **Variables Catalog** in the same dialog lists every placeholder your organization can use, with its exact spelling.
In the **Assessment report templates** panel, click **Add new template**, drop in the `.docx`, and give it a template name. The name is what analysts pick from at export time.
On any assessment, open the actions menu and choose **Export**, then **Export as Word**. Pick the template, confirm the file name, and click **Build Report**. Generation runs in the background: the dialog shows progress and offers **Download Report** when it is done, and you get a notification if you have notifications enabled. The export options stay disabled while the assessment is still collecting documents or being analyzed, and for anyone without permission to export assessments.
Only `.docx` is accepted, up to 100 MiB. `.doc`, `.dotx`, `.rtf`, and PDF uploads are rejected. If Word reports your file as `.docx` but the upload still fails, open it in Word and re-save as `.docx`; files renamed from another format fail the content check.
## Placeholder syntax
Every placeholder is double braces around an entity, a `::` separator, and a field name.
```text theme={null}
{{entity::field name}}
```
```text expandable theme={null}
{{vendor::name}}
{{vendor::description}}
{{assessment::residual risk}}
{{assessment::completed at}}
{{services::inherent risk}}
{{reviews::outcome}}
{{vendor::Data Classification}}
```
Four rules govern how they are matched:
* **Case-insensitive.** `{{Vendor::Name}}` and `{{vendor::name}}` are the same placeholder.
* **Whitespace-tolerant.** `{{ vendor :: name }}` works. Leading and trailing whitespace inside the braces is trimmed.
* **Formatting-tolerant.** A placeholder still resolves when Word has split it across several runs, which happens routinely during editing. A placeholder that spans a paragraph break also resolves in ordinary body text, but not inside a table cell, so keep placeholders in tables within a single paragraph.
* **Not nestable.** `{{vendor::{{name}}}}` is not supported. Never put braces inside a placeholder.
### Entities
| Entity | Resolves to |
| - | - |
| `vendor` | The vendor the assessment belongs to |
| `assessment` | The assessment being exported |
| `services` | All services in scope on the assessment, flattened into one value per field |
| `reviews` | The whole-assessment reviews on the assessment, flattened into one value per field |
| `intelligence` | Vendor Intelligence on the vendor (company profile, financial health, security posture, registration, people and screening) and any financial statements submitted for it |
| `agent` | AI-written prose, generated from a prompt you write in the template |
| `findings` | A repeating table row, one row per finding |
Anything else is left untouched. `{{org::name}}` stays in the document verbatim, because `org` is not a supported entity.
### Custom fields
Custom fields are addressed by their configured name, lowercased. A vendor custom field called **Data Classification** is `{{vendor::data classification}}`. Custom fields are available on `vendor`, `assessment`, and `services`.
System fields win collisions. If you create a vendor custom field named "Name", `{{vendor::name}}` still resolves to the vendor's system name field.
## AI-written sections
An `{{agent::...}}` placeholder is a prompt, not a field lookup. Coverbase runs an agent against the assessment and drops its answer into the document.
```text theme={null}
{{agent::Write a two paragraph executive summary of this vendor's security posture, aimed at a non-technical audience.}}
{{agent::List the three most material risks identified in this assessment and the compensating control for each.}}
{{agent::Summarize the vendor's incident response commitments and note any gaps against our standard.}}
```
The agent is given vendor fields, assessment fields, evaluation summaries, findings, reviews, questionnaire excerpts, and the headline of each Vendor Intelligence section as preloaded context. It can call tools to fetch vendor data, assessment data, evaluation summaries, services, findings, reviews, commitments, questionnaire responses, and full Vendor Intelligence sections for anything not already loaded.
**Agent output is rendered as formatted Word content**, not as raw text. The following markdown is honored:
| Markdown | Renders as |
| - | - |
| `**bold**` | Bold run |
| `*italic*` | Italic run |
| `***bold italic***` | Bold and italic run |
| `==highlight==` | Highlighted run |
| `- item` | Bulleted list, nesting by indentation |
| `1. item` | Numbered list, nesting by indentation |
| Blank line | Paragraph break |
Headings and markdown tables are not rendered. Ask for prose and lists.
The agent inherits the **character** formatting of the run the placeholder sits in, so a placeholder in 10pt Calibri produces 10pt Calibri prose. If a bold label precedes the placeholder in the same paragraph, put the placeholder in its own non-bold run or the generated text comes out bold.
**Paragraph** properties behave differently depending on how much the agent writes:
| Agent output | Paragraph properties |
| - | - |
| A single paragraph | The host paragraph's properties are kept, including its style, indentation, and list membership |
| Multiple paragraphs or any list | Each generated block gets its own paragraph properties. Generated lists are built with their own numbering, independent of any list the placeholder sat in |
Do not put `{{agent::...}}` inside a list item and expect the generated bullets to continue that list. A prompt that returns a list produces a fresh list with its own numbering, not a continuation of the host list. Put list-producing prompts in a plain paragraph of their own.
Each agent placeholder is an independent LLM call. A template with twenty prompts costs twenty generations, runs at most eight of them concurrently, and takes correspondingly longer. Keep prompts specific and few. Identical prompt text anywhere in the template is deduplicated and answered once.
When an agent cannot answer, the document gets a short marker instead of prose:
| Marker | Meaning |
| - | - |
| `Not available` | The agent ran but found no data to answer the prompt |
| `[Generation timed out]` | The prompt exceeded the per-prompt budget of 15 minutes |
| `[Generation failed]` | The agent errored on that prompt |
| `[Agent error]` | The whole agent batch failed to start |
## Repeating findings tables
`{{findings::::}}` placeholders turn a table row into a repeating row. Build a two-row table: a header row, and one body row holding the placeholders. Coverbase clones the body row once per finding.
| ID | Title | Risk | Due |
| - | - | - | - |
| `{{findings::new::id}}` | `{{findings::new::title}}` | `{{findings::new::risk level}}` | `{{findings::new::due date}}` |
There are two sets:
| Set | Contents |
| - | - |
| `new` | Findings raised by this assessment |
| `pre_existing` | Still-open findings on the same vendor that came from somewhere else |
### One table per risk domain
Add a risk domain between the set and the column (`{{findings::::::}}`) to narrow a table to the findings whose controls belong to that domain. Use one table per domain to get a "New Information Security findings", "New Privacy findings", "New BRM findings" structure:
**Table 1: New Information Security findings**
| ID | Title | Risk |
| - | - | - |
| `{{findings::new::Information Security::id}}` | `{{findings::new::Information Security::title}}` | `{{findings::new::Information Security::risk level}}` |
**Table 2: New Privacy findings**
| ID | Title | Risk |
| - | - | - |
| `{{findings::new::Privacy::id}}` | `{{findings::new::Privacy::title}}` | `{{findings::new::Privacy::risk level}}` |
Write the domain exactly as it is named in **Configuration → Risk domains**; matching ignores case and surrounding spaces. A finding's domain comes from the control it was raised against: the control section's risk domain if it has one, otherwise the control set's. Findings not raised against a control (and controls with no domain at either level) appear in the unscoped tables only.
If you would rather keep one table and label each row, use the `risk domain` column instead:
| Title | Risk domain |
| - | - |
| `{{findings::new::title}}` | `{{findings::new::risk domain}}` |
Rules that apply to findings tables:
* **A row belongs to exactly one set.** The first set referenced in the row wins. Placeholders from the other set, or from a different risk domain, in that same row resolve to empty text, so do not mix `new` and `pre_existing`, or two domains, in one row.
* **Empty sets collapse to one row.** A set with no findings renders a single row reading "No new findings" or "No pre-existing open findings", with " for ``" appended when the table is scoped to a domain.
* **A misspelled risk domain is reported.** The table renders its empty state and the placeholder is recorded on the generated document as an unknown field, so a typo does not quietly pass as "no findings in this domain".
* **Tables anywhere are covered.** Body tables, tables nested inside cells, and tables in headers and footers all expand.
* **Only inside tables.** A `{{findings::...}}` placeholder in ordinary body text is left in the document verbatim.
* **Capped at 100 rows per set.** Larger sets are truncated.
* **Keep each placeholder in one cell.** A placeholder split across two cells is not matched.
## Signature anchors
If the report is going out for signature, place DocuSign anchor strings in the template. They pass through generation as ordinary text and are read when the signature request is created, positioning each signer's tabs at the anchor.
| Anchor | Purpose |
| - | - |
| `/sn1/` through `/sn5/` | Signature block for signer 1 through 5 |
| `/date_signed1/` through `/date_signed5/` | Date-signed tab |
| `/date1/` through `/date5/` | Date tab |
| `/full_name1/`, `/first_name1/`, `/last_name1/` | Name tabs, numbered per signer |
| `/title1/` through `/title5/` | Signer title tab |
| `/organization1/` through `/organization5/` | Signer organization tab |
Anchors are plain text in the document. Set them in white or a small font size if you do not want them visible in the final PDF.
Two things to know about how they are handled:
* **Signature anchors are recorded at generation time.** Only `/sn1/` through `/sn5/` are scanned for and stored on the generated report. The other tab anchors are read from the document when the signature request is created, so they do not need to be recorded earlier.
* **A missing anchor blocks sending.** Creating a signature request fails if a signer is assigned an anchor that is not present in the document. If you add a third signer, add `/sn3/` to the template first.
* **The number ties a tab to a signer.** `/sn2/` creates the second signer, and `/title2/` or `/date_signed2/` place that signer's tabs. A tab anchor numbered for a signer with no matching `/snN/` in the document is ignored.
## What happens to unresolved placeholders
The placeholder text stays in the document. This is deliberate: a blank space hides the problem, while a visible `{{vendor::use cases}}` tells the report author that the field is empty in Coverbase. Fill in the source data and re-export.
`{{intelligence::...}}` placeholders are the exception. An empty one renders `Not available`, because many of those fields are legitimately empty for a given vendor.
The placeholder text stays in the document, and the field is recorded on the generated document as an unknown field. This usually means a typo, or a custom field that was renamed or disabled after the template was written.
Nothing happens at all. The text is not recognized as a placeholder and passes through untouched.
The cell renders empty and the column is recorded as an unknown field. The row still repeats correctly.
## Authoring tips
* **Type placeholders in one go.** Word splits text into runs when you edit mid-word, add a spellcheck correction, or paste. Substitution handles split runs, but the cleanest way to avoid surprises is to type the whole placeholder without stopping, or paste it as plain text.
* **Avoid autocorrect damage.** Word can turn `::` or straight quotes inside a prompt into other characters. Check that a placeholder still reads exactly as you typed it.
* **Style the placeholder, not the paragraph.** A placeholder inherits the formatting of its own run. If the label before it is bold and you do not want bold output, make sure the placeholder itself is not bold.
* **Test with a real assessment.** Export against an assessment that has findings, several services, and completed reviews. Empty-state behavior differs from populated behavior.
* **Keep one template per audience.** A short executive template and a long evidence template beat one template with everything in it, because agent prompts you do not need still cost a generation.
When a previously generated report is regenerated in place rather than exported fresh, findings tables are left as they are. Findings rows are expanded on the export path only.
# Evidence packaging and the due-diligence file
Source: https://docs.coverbase.com/reporting/due-diligence-file
Produce the complete due-diligence file for one third party: the full vendor report with profile, assessments, findings, contracts, obligations, documents, monitoring, notes and the audit trail, plus bulk document archives and structured exports.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
An examiner, an internal auditor or an acquirer asks the same question: show me everything you hold on this third party, and show me how you decided. Coverbase answers it from the vendor record itself, without anyone assembling a folder by hand.
## The full vendor report
From a vendor's page, open **Actions** and choose **Build report** to build a single branded PDF of the whole relationship. Choose the report type and the sections, and Coverbase builds it in the background and notifies you when it is ready. Building a report needs permission to export vendors across the organization, and the redesigned vendor and service reports are enabled per workspace: if **Build report** is missing, ask your Coverbase contact.
Risk posture, profile and the latest assessment outcome. A few pages, for a committee pack.
Adds services, assessments, findings, contracts, obligations and documents.
**Everything**, including the bill of materials, notes, and the complete audit trail.
A full vendor report carries, in one document:
| Section | What it contains |
| - | - |
| Vendor profile | Identity, corporate registration, description, use case, owners, tier and criticality |
| Risk profile | Scores by risk domain, the scale each was rated on, and the inherent-risk basis |
| Services and engagements | Each service, its business use, its own risk profile and its owners |
| Assessments | Every assessment run against the vendor, its scope, outcome, approval option and reviewer |
| Findings | Open and closed findings, severity, owner, and remediation state |
| Contracts | The contract family, key terms, dates and values |
| Obligations | Contractual obligations extracted and tracked, with status |
| Documents | The document inventory: what was collected, when, and from where |
| Monitoring | Radar signals raised against the vendor and how each one was closed out |
| Performance | Vendor performance scoring where enabled |
| Procurement | Purchase orders and procurement records |
| Bill of materials | Components and fourth parties behind the service |
| Notes | The comment timeline, in order |
| Audit trail | Every recorded action on the record, with actor and timestamp |
The report carries **your** brand: your logo and accent color in the running header, the vendor's mark on the masthead, and your third-party contact address in the footer. It is a document you can hand to a regulator without reformatting it.
The same three-tier export exists at **service** level, for programs that diligence per service rather than per legal entity, and at **assessment** level for a single review cycle.
## Everything else in the package
Select the vendor's documents and download them as a single `.zip`: SOC 2 reports, certificates, policies, questionnaire attachments, signed contracts, and anything else collected. The archive builds in the background and lands in your documents when it is ready. Bulk document export is org-scoped and gated on an export permission, so it is deliberately not something an assigned-only reader can trigger.
A full assessment PDF adds per-control evidence: the evaluation, the citation, the evidence snippet images, the reviews, follow-ups, notes and the activity log for that assessment. This is the layer that shows *how* a control was judged, not only what the judgment was. See [Reporting overview](/reporting/overview).
Upload your firm's house report as a `.docx` with placeholders, and Coverbase fills it per assessment from live data, including AI-answered narrative sections. Your layout, your headings, your language. See [Assessment report templates](/reporting/assessment-report-templates).
**Export as Excel** in the same **Actions** menu builds a workbook of the vendor, one sheet per module of the vendor page: an overview, services, engagements, assessments, findings, contracts, obligations, documents, monitoring, performance and SLAs, procurement, notes and activity. Where the PDF caps each table so one record cannot dominate the read, the workbook carries every row, for filtering and sampling.
Org-level `.xlsx` exports cover many assessments at once: a filtered list of assessments, or every assessment result within a date range, for the population testing an examiner asks for rather than one file at a time.
The [Export API](/export-api-concepts) returns vendors, services, assessments, evaluations, controls, findings, obligations and contracts as JSON, filtered and paginated, so a package can be assembled on a schedule into your GRC platform, warehouse or regulator submission pipeline.
`GET /v1/system_audit_log` returns the organization-wide record of every action, including public-API calls and AI assistant tool calls, filterable and exportable. See [Audit trails](/security/audit-trails).
## Assembling an examination package
Filter the vendor list to the population in scope: critical activities, a business line, a tier, a data classification, a jurisdiction, or a custom field of your own. Save it as a view so the same population reproduces next time.
Run the bulk assessment `.xlsx` for the date range under examination. This is the sampling frame.
For each vendor the examiner picks, export the **Full** vendor report and the document archive. Between them they carry the profile, the diligence, the decisions, the paper, the monitoring, and the audit trail.
Your control sets, your workflow definitions, your roles and their permission matrices, and the [regulatory alignment](/security/regulatory-alignment) mapping, which shows what the program was designed against.
Run this once before you need it. The week an examination opens is a bad time to find out what the package does and does not contain.
## Related
Every reporting surface and which one to use.
What the package is evidencing, mapped to the guidance.
The structured, programmatic path.
The record behind every decision in the package.
# Reporting overview
Source: https://docs.coverbase.com/reporting/overview
How Coverbase turns assessment data into deliverable documents: custom Word report templates, standard exports, and the placeholder system that fills them.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
Coverbase produces two kinds of assessment deliverable. Standard exports give you a fixed, complete dump of an assessment. Custom Word report templates give you a document that looks exactly like your firm's house report, filled in automatically from live assessment data.
## Reporting surfaces
Upload a `.docx` file containing placeholders. Coverbase clones it per assessment, substitutes vendor, assessment, service, review, and finding data, and returns a finished Word document.
Every placeholder you can write in a template, what it resolves to, and how it is formatted.
A fixed-layout PDF of a single assessment, no template required. Choose an executive summary, standard, or full export, and toggle sections such as findings, reviews, follow-ups, notes, evidence snippet images, and the activity log.
One assessment's evaluations as `.xlsx` or `.csv`, from **Export as Excel** or **Export as CSV** on the assessment. Toggle the executive summary, follow-ups, notes, activity log, SLA timings and reviews. The `.xlsx` can also carry a sheet of the evidence behind each evaluation.
Org-level `.xlsx` exports covering many assessments at once: a filtered list of assessments, or every assessment result within a date range. These are not per-assessment exports and have no section toggles.
Pull the underlying assessment, evaluation, and finding objects as JSON and build reporting in your own BI or GRC stack.
The complete file for one third party: a full vendor report covering profile, assessments, findings, contracts, obligations, documents, monitoring, notes and the audit trail, plus the document archive behind it.
## Which one to use
| You want | Use |
| - | - |
| A branded, client-ready report with your own narrative sections and layout | [Custom Word report template](/reporting/assessment-report-templates) |
| A complete record of everything in one assessment, including evidence snippets and the activity log | Standard PDF export, full mode |
| One assessment's evaluations and evidence in a spreadsheet | Assessment spreadsheet export |
| Many assessments in a spreadsheet for filtering or pivoting | Bulk `.xlsx` export |
| Assessment data in your own warehouse, dashboard, or regulator submission pipeline | [Export API](/export-api-concepts) |
| Everything you hold on one third party, for an examiner, an auditor, or an acquirer | [Due-diligence file](/reporting/due-diligence-file) |
## How a custom report is generated
A `.docx` file with placeholders is uploaded once, from the **Assessment report templates** panel in **Configuration > Assessment Settings > Reports**, and reused across assessments.
From the assessment page, choose **Export**, then **Export as Word**, and pick the template and a filename. The request returns immediately with a document ID; generation runs as a background job.
Static placeholders are read straight from the database. `{{agent::...}}` placeholders are answered by an LLM that has the assessment loaded as context. Findings table rows are cloned once per finding.
The generated `.docx` is stored as an org document. The export dialog tracks progress and offers the download when the job completes.
Custom Word report templates are gated per organization. If the export option is not visible on the assessment page, an admin needs to turn on **Assessment report templates** in **Configuration > Assessment Settings > Reports**. If it is visible but disabled, the assessment has no results to export yet (it is still collecting documents or being analyzed), or your role lacks permission to export assessments.
## Terminology
The mechanism has a few names in the wild. This documentation uses **placeholder** throughout.
| Term | Where you will see it |
| - | - |
| Placeholder | This documentation, and the stored `placeholder_values` map on a generated report |
| Template variable | The in-app help text on the template upload dialog |
| Token | The [Admin and setup guide](/user-guides/admin-setup), in the report templates step |
| Tag, merge field, mustache | Common informal names, since the syntax borrows `{{ }}` from Mustache |
The syntax resembles Mustache but is not Mustache. There are no sections, no partials, no inverted blocks, and no nesting. Everything Coverbase supports is listed in the [placeholder reference](/reporting/template-placeholders).
# Template placeholder reference
Source: https://docs.coverbase.com/reporting/template-placeholders
Every placeholder available in a Coverbase Word report template, what it resolves to, and how the value is formatted.
For AI agents: a documentation index is available at [https://docs.coverbase.com/llms.txt](https://docs.coverbase.com/llms.txt). This page is also available in markdown by appending .md to the URL.
This is the complete list of placeholders you can write in an [assessment report template](/reporting/assessment-report-templates). Field names are matched case-insensitively, and whitespace around the entity, the `::`, and the field name is ignored.
The same list is in the product: **Variables Catalog** in the **Add new assessment report template** dialog shows every placeholder with its exact spelling, including your organization's enabled custom fields, and copies one when you click it.
## Vendor
`{{vendor::}}` resolves against the vendor that the assessment belongs to.
| Placeholder | Value |
| - | - |
| `{{vendor::name}}` | Vendor name |
| `{{vendor::description}}` | Vendor description |
| `{{vendor::location}}` | Vendor headquarters location |
| `{{vendor::use cases}}` | The vendor's use case text |
| `{{vendor::relationship owners}}` | Comma-separated display names of the relationship owners |
| `{{vendor::risk analysts}}` | Comma-separated display names of the risk analysts |
| `{{vendor::watchers}}` | Comma-separated display names of the watchers |
| `{{vendor::dri}}` | The vendor service requestor recorded on the vendor |
| `{{vendor::}}` | Any enabled vendor custom field, addressed by its name |
## Assessment
`{{assessment::}}` resolves against the assessment being exported. Dates are formatted `YYYY-MM-DD` in the timezone supplied at export time.
| Placeholder | Value |
| - | - |
| `{{assessment::residual risk}}` | Residual risk level name. Falls back to `Low` when no level is set |
| `{{assessment::inherent risk}}` | Inherent risk level name |
| `{{assessment::assignee}}` | Display name of the assignee |
| `{{assessment::approval option}}` | Label of the selected approval option |
| `{{assessment::completed at}}` | Date the assessment was completed |
| `{{assessment::next vendor assessment}}` | The vendor's next assessment date, or `Never` when reassessment is disabled |
| `{{assessment::recommendation}}` | `Status: recommendation text`, using whichever parts are present |
| `{{assessment::assessment score}}` | Average score, else percent score with a `%` suffix, else summed score, to one decimal place |
| `{{assessment::vendor documents}}` | Bulleted list of the non-archived supporting document names |
| `{{assessment::summary}}` | The assessment summary body, flattened to plain text. Markdown headings become uppercase lines and list markers become bullets |
| `{{assessment::open issues}}` | Bulleted list of open issues as `#` |
| `{{assessment::}}` | Any enabled assessment custom field, addressed by its name |
## Services
`{{services::}}` covers **all** services in scope on the assessment, flattened into a single value.
When the assessment has one service, the value is the bare field value. When it has more than one, the value becomes a bulleted block of `• Service name - value`, and services with no value for that field are dropped. When the assessment has no services, every services placeholder is empty.
| Placeholder | Value |
| - | - |
| `{{services::name}}` | Comma-separated list of service names. This one is always comma-separated, never bulleted |
| `{{services::description}}` | Service descriptions |
| `{{services::inherent risk}}` | Inherent risk level name per service |
| `{{services::relationship owners}}` | Relationship owners per service |
| `{{services::watchers}}` | Watchers per service |
| `{{services::next assessment date}}` | Next assessment date per service, or `Never` |
| `{{services::}}` | Any enabled service custom field, addressed by its name |
## Reviews
`{{reviews::}}` covers the whole-assessment reviews on the assessment. Domain-scoped reviews from the risk profile are excluded, matching the other exports.
Formatting follows the same rule as services: a single review renders bare, several reviews render as a bulleted block keyed by a row label. The row label is the review name, falling back to the reviewer, falling back to `Review 1`, `Review 2`, and so on.
| Placeholder | Value |
| - | - |
| `{{reviews::summary}}` | One self-contained line per review, `