Dashboard

VerifyTrust — Stateless Screening API

VerifyTrust provides AML, PEP, sanctions, RCA, and watchlist screening signals through a privacy-first API.

VerifyTrust does not make final compliance decisions, manage cases, file SARs, store customer screening profiles, or replace a regulated compliance program. Clients remain responsible for final review, escalation, retention, and regulatory obligations.

Looking for the original KYC + screening flow? That endpoint (POST /api/kyc/v1/submit_plus) and its companion POST /api/kyc/v1/generate_report are unchanged. The new API documented here is a separate, additive surface.

Endpoints

Method Path Purpose
POST /api/compliance/v1/screen Stateless individual screening
POST /api/compliance/v1/rescreen Stateless re-screening of a subject without VerifyHuman holding the prior subject profile

Both endpoints require an API key with the verifycompliance scope (X-API-Key header), and bill against your VerifyTrust plan via the existing per-attempt billing system.

Endpoint Default credit cost
screen 60 credits
rescreen 30 credits

Authentication failures, validation failures, and pre-provider 5xx errors are not billed. Provider unavailability is recorded as a non-billable attempt.

Decision language

The new API uses a screening-signal decision enum, never a final compliance outcome:

Score range Level Decision
0–29 low clear
30–59 medium review
60–100 high high_risk_review

Words like approved, rejected, pass, and fail are deliberately never emitted by this layer.

POST /api/compliance/v1/screen

Request

POST /api/compliance/v1/screen
X-API-Key: vhk-...
Content-Type: application/json
{
  "client_reference_id": "customer_123",
  "subject": {
    "type": "individual",
    "first_name": "Jane",
    "last_name": "Doe",
    "date_of_birth": "1985-04-12",
    "gender": "female",
    "country": "US"
  },
  "screening": {
    "lists": ["sanctions", "pep", "rca", "wanted"],
    "provider": "default"
  },
  "metadata": {
    "workflow": "onboarding"
  }
}
Field Required Notes
subject.type yes Must be individual in this phase.
subject.first_name yes
subject.last_name yes
subject.date_of_birth no YYYY-MM-DD if present.
subject.gender no
subject.country no ISO-3166 alpha-2 if present (e.g. US).
client_reference_id no Opaque client identifier; treated as a reference.
screening.lists no Subset of sanctions, pep, rca, wanted.
screening.provider no default (recommended). Contact support for alternative providers.
metadata no Flat key/value bag, scrubbed for obvious PII.

Response — clear result

{
  "id": "vcmp_01HXX...",
  "object": "compliance.screening",
  "livemode": true,
  "created": 1777057500,
  "status": "completed",
  "client_reference_id": "customer_123",
  "subject_type": "individual",
  "provider": {
    "normalized": true,
    "raw_response_included": false
  },
  "screening": {
    "lists_checked": ["sanctions", "pep", "rca", "wanted"],
    "screened_at": "2026-04-24T00:00:00Z",
    "search_mode": "standard",
    "provider_reference_id": null
  },
  "risk": {
    "score": 0,
    "level": "low",
    "decision": "clear",
    "reasons": []
  },
  "matches": [],
  "flags": [],
  "data_retention": {
    "input_payload_stored": false,
    "result_payload_stored": false,
    "raw_provider_response_stored": false,
    "biometric_media_stored": false,
    "retention_model": "ephemeral_processing_only"
  },
  "metadata": { "workflow": "onboarding" }
}

Response — PEP review

{
  "id": "vcmp_01HXX...",
  "object": "compliance.screening",
  "status": "completed",
  "risk": {
    "score": 45,
    "level": "medium",
    "decision": "review",
    "reasons": ["pep_possible_match"]
  },
  "flags": ["PEP_POSSIBLE_MATCH"]
}

Response — sanctions high-risk review

{
  "id": "vcmp_01HXX...",
  "object": "compliance.screening",
  "status": "completed",
  "risk": {
    "score": 85,
    "level": "high",
    "decision": "high_risk_review",
    "reasons": ["sanctions_strong_match"]
  },
  "flags": ["SANCTIONS_STRONG_MATCH"]
}

Errors

{
  "error": {
    "type": "invalid_request",
    "code": "invalid_subject",
    "message": "The subject payload is invalid."
  }
}
{
  "error": {
    "type": "provider_unavailable",
    "code": "compliance_provider_unavailable",
    "message": "Compliance screening provider is temporarily unavailable."
  }
}

Validation errors never echo PII — they reference field names only.

Stateless Re-screening

VerifyHuman does not store customer screening profiles. To re-screen a subject, the client sends the subject payload again along with the previous screening ID or previous result summary. VerifyHuman re-runs the screening and returns a new result.

POST /api/compliance/v1/rescreen

{
  "previous_screening_id": "vcmp_01HXOLD",
  "client_reference_id": "customer_123",
  "subject": {
    "type": "individual",
    "first_name": "Jane",
    "last_name": "Doe",
    "date_of_birth": "1985-04-12",
    "gender": "female",
    "country": "US"
  },
  "screening": {
    "lists": ["sanctions", "pep", "rca", "wanted"],
    "reason": "periodic_rescreen",
    "provider": "default"
  },
  "previous_result_summary": {
    "risk_score": 12,
    "risk_level": "low",
    "flags": []
  },
  "metadata": { "workflow": "quarterly_refresh" }
}

screening.reason must be one of:

The response is identical to /screen plus an additional rescreen block:

"rescreen": {
  "previous_screening_id": "vcmp_01HXOLD",
  "reason": "periodic_rescreen",
  "risk_change": "risk_increased"
}

risk_change is one of risk_increased, risk_decreased, risk_unchanged, or unknown_without_prior_result (when no previous_result_summary is supplied).

Webhooks

The new stateless endpoints emit four additive webhook event types:

Event When
compliance.screening.completed /api/compliance/v1/screen succeeded
compliance.screening.failed /api/compliance/v1/screen failed after auth + validation (e.g. provider unavailable)
compliance.rescreen.completed /api/compliance/v1/rescreen succeeded
compliance.rescreen.risk_changed rescreen succeeded and risk_change is risk_increased or risk_decreased (never for risk_unchanged or unknown_without_prior_result)

These are delivery notifications for screening results — they do not create a compliance workflow, case record, or customer profile inside VerifyHuman. Webhook payloads are generated from the same public-safe response returned by the API. They do not include the subject payload, raw provider responses, or watchlist source records.

Subscribe to these event types from your existing webhook endpoint (Dashboard → Webhooks). All payloads use the standard VerifyHuman HMAC-SHA256 signing scheme. See webhooks.md for full payload examples, signature-verification helper code, and replay-window guidance (5 minutes recommended).

Existing legacy VerifyTrust webhook events (compliance.completed, compliance.hit_detected, compliance.report_ready) remain unchanged and continue to flow from the legacy KYC+ pipeline.

Privacy and data retention

Both new endpoints preserve VerifyHuman's data-processor posture:

The data_retention block on every response is a constant statement of these facts.