Compliance
This capability is granted by an API key scoped to the `` product (product face). See the product reference below.
Data-subject-request + retention state-machine capability. The regulation-agnostic skeleton: the GDPR/CCPA request FSM (submit -> verify -> cooling_off -> process -> complete), the SLA/overdue tracker, the retention -tier taxonomy (HOT/WARM/COLD/ARCHIVE) + legal holds, and the Article-30 append-only processing log. The actual erasure/export/enforce runs PRODUCT-SIDE: when a request enters processing the service fans it out to the org's pre-registered handler via the webhook-egress capability, and the product calls back /complete. I4: own Postgres store, no product data, no callback URLs (webhook-egress owns the per-org handler registry).
- Group: Governance & platform
- Contract:
contracts/compliance/v1/openapi.yaml - Public base:
https://api.vagarylabs.com(the consolidated API gateway — one host, per-brand siblingapi.<zone>) - Auth: a product API key (
vgk_…) issued from the console —Authorization: Bearer vgk_… - Product face (customer-keyed):
https://api.vagarylabs.com/product/v1/compliance/requests
Endpoints
| Method | Path | Summary |
|---|---|---|
POST | /v1/compliance/requests | Submit a data-subject request (erasure/export/access/rectification/consent) |
GET | /v1/compliance/requests | List the org's requests (filter by subject_ref / status / request_type) |
GET | /v1/compliance/overdue | Active requests past their regulation's statutory response window (GDPR 30d / CCPA 45d) |
GET | /v1/compliance/requests/{request_id} | One request's lifecycle state |
POST | /v1/compliance/requests/{request_id}/verify | Confirm the subject-verification token (pending -> cooling_off) |
POST | /v1/compliance/requests/{request_id}/process | Run the erasure (cooling_off -> processing) — capability fan-out + product-handler dispatch |
POST | /v1/compliance/requests/{request_id}/complete | Product handler reports its local body done or failed (processing -> completed |
POST | /v1/compliance/requests/{request_id}/cancel | Cancel a pre-processing request (pending |
POST | /v1/compliance/requests/{request_id}/reject | Reject a pre-processing request by policy/operator (pending |
GET | /v1/compliance/audit | The Article-30 append-only processing log (filter by request_id / subject_ref) |
POST | /v1/compliance/retention/policies | Register/update a retention policy (HOT/WARM/COLD/ARCHIVE tier taxonomy) |
GET | /v1/compliance/retention/policies | The org's retention policies |
POST | /v1/compliance/retention/due | Surface retention decisions for a subject (due/blocked/action) given product-supplied data ages |
POST | /v1/compliance/legal-holds | Create a legal hold (fail-closed deletion block) |
GET | /v1/compliance/legal-holds | The org's legal holds |
POST | /v1/compliance/legal-holds/{hold_id}/release | Release (deactivate) a legal hold |
GET | /v1/compliance/residency/regions | The regions this deployment ACTUALLY serves (honest, non-aspirational) |
PUT | /v1/compliance/residency | Pin this org's data to a region |
GET | /v1/compliance/residency | This org's residency pin (pinned=false when none) |
DELETE | /v1/compliance/residency | Remove this org's residency pin |
POST | /v1/compliance/residency/check | THE ENFORCEMENT SEAM — may this org's data be processed in this region? |
GET | /v1/compliance/trust-center | The trust-center DATA source (honest by construction) |
POST | /v1/compliance/documents/{kind}/accept | Click-through self-sign a document (dpa |
GET | /v1/compliance/documents/acceptances | This org's acceptance evidence, newest-first |
GET | /v1/compliance/documents/{kind}/current | The newest acceptance of a kind ("has this org signed the DPA?") |
GET | /health | liveness |
GET | /metrics | Prometheus |
Schemas
CapabilityErasureResult
One capability's outcome in an erasure fan-out. matched is reported separately from deleted / pseudonymized so a zero-match is never readable as a successful erasure.
| Field | Type | Description |
|---|---|---|
capability | string | e.g. session-store, revenue-tracking |
outcome | string | erased/pseudonymized/zero_match/no_subject_data are SETTLED; the rest mean the subject's data may still be present and downgrade the run to partial. |
disposition | string | pseudonymize = statutory-retention record, unlinked not deleted |
matched | integer | rows matching the subject; null when the capability did not report it |
deleted | integer | |
pseudonymized | integer | rows whose subject link was severed while the record was preserved |
http_status | integer | |
detail | string | why — carries the evidence for no_subject_data / not_implemented |
FanoutReport
The result of the in-cluster capability erasure fan-out. complete is the ONLY status that may advance the request toward a successful terminal state.
| Field | Type | Description |
|---|---|---|
status | string | complete = every capability settled AND at least one matched. no_data_found = every capability clean but none matched (usually a wrong selector — NOT an erasure). partial = at least one capability unsettled. disabled = fan-out not enabled in this deployment. |
reason | string | |
capabilities | array | |
unsettled | array | capabilities that may still hold the subject data |
Regulation
RequestType
Status
canonical superset (§27.6) — pending/cooling_off/processing/completed/failed/rejected/cancelled
SubmitRequest
| Field | Type | Description |
|---|---|---|
organization_id | string | product-tier tenant (I6) — verified against the token, never trusted alone |
regulation | object | |
request_type | object | |
subject_ref | string | OPAQUE product subject identifier (the product-tier user id) — never interpreted here |
require_verification | boolean | default true (fail-safe); when true the request sits in pending until /verify |
details | object | OPAQUE product-owned metadata — stored, never interpreted (I4). ONE reserved key: selectors, read by the erasure fan-out (see POST .../process). subject_ref is the default for every scalar selector, so selectors is only needed when a capability keys the subject differently. |
RequestRecord
| Field | Type | Description |
|---|---|---|
request_id | string | |
organization_id | string | |
subject_ref | string | |
regulation | object | |
request_type | object | |
status | object | |
require_verification | boolean | |
verification_token | string | returned ONCE at submit (never on GET) when require_verification — deliver to the subject out-of-band |
details | object | |
dispatch_ref | string | |
last_error | string | |
created_at | string | |
cooling_off_started_at | string | |
processing_started_at | string | |
completed_at | string |
AuditEvent
| Field | Type | Description |
|---|---|---|
id | integer | |
request_id | string | |
action | string | |
actor | string | |
subject_ref | string | |
regulation | string | |
details | object | |
created_at | string |
Generated by scripts/gen-capability-docs.py from contracts/compliance/v1/openapi.yaml — the contract IS the source of truth; edit the contract, not this page.