Webhook Events
Complete reference of all webhook events in TrustGate. This document is generated from the actual backend codebase and reflects only events that are currently implemented and fired.
Payload Envelope
Every webhook delivery uses a standard envelope structure:
{
"event_type": "applicant.reviewed",
"event_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"timestamp": "2026-02-04T14:30:00Z",
"tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"correlation_id": null,
"data": {
// Event-specific fields (see below)
}
}
| Field | Type | Description |
|---|---|---|
event_type | string | The event type identifier |
event_id | UUID | Unique event ID for idempotency |
timestamp | ISO 8601 datetime | When the event was created |
tenant_id | UUID | Your tenant ID |
correlation_id | string or null | Optional tracing ID passed through your system |
data | object | Event-specific payload (varies by event type) |
Event Summary
The table below lists all events that are currently fired by the TrustGate backend. Events are delivered through two systems: the primary webhook service (tenant settings-based) and the integrations webhook system (webhook config-based).
| Event Type | Trigger | Category |
|---|---|---|
applicant.submitted | Applicant submits verification via the SDK | Applicant |
applicant.reviewed | Applicant is manually approved or rejected by a reviewer | Applicant |
applicant.verification_complete | All verification checks finish processing (real or sandbox) | Applicant |
screening.completed | AML/sanctions screening finishes for an applicant | Screening |
document.verified | Document verification completes (OCR, fraud checks) | Document |
case.created | A manual review case is created (auto or manual) | Case |
session.completed | A verification session reaches a terminal state | Session |
test.ping | Manually triggered via the webhook test endpoint | Testing |
workflow.action.webhook | A workflow automation action sends a custom webhook | Workflow |
Subscribable Events
When configuring a webhook via the integrations API, you can subscribe to the following event types:
applicant.created
applicant.updated
applicant.approved
applicant.rejected
applicant.withdrawn
document.uploaded
document.verified
document.rejected
screening.started
screening.completed
screening.hit
case.created
case.resolved
case.assigned
You can also subscribe to * to receive all events.
Note: The subscribable events list includes some event names that are not yet fired by the backend (such as applicant.created, applicant.withdrawn, screening.started, and case.assigned). These are reserved for future implementation. The events in the summary table above are the ones actively dispatched today.
Applicant Events
applicant.submitted
Fired when an applicant submits their verification through the SDK. This occurs after documents are uploaded and before verification processing begins.
Source: backend/app/api/v1/sdk.py -- SDK submit endpoint
{
"event_type": "applicant.submitted",
"event_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"timestamp": "2026-02-04T14:00:00Z",
"tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"correlation_id": null,
"data": {
"applicant_id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "user_123",
"status": "in_progress",
"submitted_at": "2026-02-04T14:00:00Z",
"documents_count": 2,
"steps_completed": ["document_upload", "selfie"]
}
}
| Field | Type | Description |
|---|---|---|
applicant_id | UUID | The applicant's internal ID |
external_id | string or null | Your external user identifier |
status | string | Always "in_progress" at submission time |
submitted_at | ISO 8601 or null | When the applicant submitted |
documents_count | integer | Number of documents uploaded |
steps_completed | array of strings | SDK steps completed before submission |
applicant.reviewed
Fired when a reviewer manually approves or rejects an applicant through the dashboard.
Source: backend/app/api/v1/applicants.py -- review applicant endpoint
{
"event_type": "applicant.reviewed",
"event_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"timestamp": "2026-02-04T15:00:00Z",
"tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"correlation_id": null,
"data": {
"applicant_id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "user_123",
"status": "approved",
"risk_score": 25,
"risk_level": "low",
"review_decision": "manual_approved",
"reviewed_by": "d4e5f6a7-b8c9-0123-def0-456789012345",
"reviewed_at": "2026-02-04T15:00:00Z",
"flags": []
}
}
| Field | Type | Description |
|---|---|---|
applicant_id | UUID | The applicant's internal ID |
external_id | string or null | Your external user identifier |
status | string | "approved" or "rejected" |
risk_score | integer or null | Computed risk score (0-100) |
risk_level | string or null | "low", "medium", or "high" |
review_decision | string | One of: manual_approved, manual_rejected, auto_approved, auto_rejected |
reviewed_by | UUID or null | The reviewer's user ID |
reviewed_at | ISO 8601 or null | When the review occurred |
flags | array of strings | Any flags on the applicant (e.g., "screening_hit") |
applicant.verification_complete
Fired when all verification processing finishes for an applicant. This includes biometric checks, document verification, screening, and risk assessment. Also fires for sandbox mode verifications (with sandbox: true in the payload).
Source: backend/app/api/v1/sdk.py -- verification processing logic
{
"event_type": "applicant.verification_complete",
"event_id": "d4e5f6a7-b8c9-0123-def0-567890123456",
"timestamp": "2026-02-04T14:05:00Z",
"tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"correlation_id": null,
"data": {
"applicant_id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "user_123",
"status": "approved",
"biometrics_verified": true,
"screening_status": "clear",
"risk_level": "low",
"verification_results": {
"biometrics": { "face_match": true, "liveness": true },
"screening": { "watchlist": { "status": "clear", "hit_count": 0 } },
"risk": { "overall_level": "low", "score": 25 }
}
}
}
| Field | Type | Description |
|---|---|---|
applicant_id | UUID | The applicant's internal ID |
external_id | string or null | Your external user identifier |
status | string | Final applicant status after verification |
sandbox | boolean | Present and true only for sandbox mode verifications |
biometrics_verified | boolean | Whether biometric checks passed |
screening_status | string | "clear", "hit", or "not_run" |
risk_level | string | "low", "medium", "high", or "unknown" |
verification_results | object | Full verification result breakdown |
Screening Events
screening.completed
Fired when AML/sanctions screening finishes for an applicant. The convenience function is defined for this event, and it can be triggered through the webhook service or via workflow dispatching.
Source: backend/app/services/webhook.py -- send_screening_completed_webhook()
{
"event_type": "screening.completed",
"event_id": "e5f6a7b8-c9d0-1234-ef01-678901234567",
"timestamp": "2026-02-04T14:10:00Z",
"tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"correlation_id": null,
"data": {
"applicant_id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "user_123",
"screening_check_id": "f6a7b8c9-d0e1-2345-f012-789012345678",
"status": "clear",
"hit_count": 0,
"check_types": ["sanctions", "pep", "adverse_media"],
"list_version": "2026-02-04",
"completed_at": "2026-02-04T14:10:00Z"
}
}
| Field | Type | Description |
|---|---|---|
applicant_id | UUID | The applicant's internal ID |
external_id | string or null | Your external user identifier |
screening_check_id | UUID | The screening check record ID |
status | string | "clear", "hit", or "error" |
hit_count | integer | Number of screening hits found |
check_types | array of strings | Check categories run (e.g., "sanctions", "pep", "adverse_media") |
list_version | string or null | Version/date of the screening lists used |
completed_at | ISO 8601 | When screening completed |
Document Events
document.verified
Fired when document verification completes, including OCR extraction and fraud signal analysis.
Source: backend/app/services/webhook.py -- send_document_verified_webhook()
{
"event_type": "document.verified",
"event_id": "a7b8c9d0-e1f2-3456-0123-890123456789",
"timestamp": "2026-02-04T14:08:00Z",
"tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"correlation_id": null,
"data": {
"applicant_id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "user_123",
"document_id": "b8c9d0e1-f234-5678-1234-901234567890",
"document_type": "passport",
"status": "verified",
"ocr_confidence": 0.95,
"fraud_signals": [],
"security_features_detected": ["mrz_valid", "hologram_detected"],
"verified_at": "2026-02-04T14:08:00Z"
}
}
| Field | Type | Description |
|---|---|---|
applicant_id | UUID | The applicant's internal ID |
external_id | string or null | Your external user identifier |
document_id | UUID | The document record ID |
document_type | string | Document type (e.g., "passport", "drivers_license", "id_card") |
status | string | "verified", "rejected", or "review" |
ocr_confidence | float or null | OCR extraction confidence (0.0 to 1.0) |
fraud_signals | array of strings | Detected fraud indicators |
security_features_detected | array of strings | Security features found on the document |
verified_at | ISO 8601 | When verification completed |
Case Events
case.created
Fired when a manual review case is created, either automatically (e.g., triggered by a screening hit) or manually by a user.
Source: backend/app/services/webhook.py -- send_case_created_webhook()
{
"event_type": "case.created",
"event_id": "c9d0e1f2-3456-7890-2345-012345678901",
"timestamp": "2026-02-04T14:12:00Z",
"tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"correlation_id": null,
"data": {
"applicant_id": "550e8400-e29b-41d4-a716-446655440000",
"external_id": "user_123",
"case_id": "d0e1f234-5678-9012-3456-123456789012",
"case_type": "screening_hit",
"priority": "high",
"reason": "Potential sanctions match detected",
"auto_created": true,
"created_at": "2026-02-04T14:12:00Z"
}
}
| Field | Type | Description |
|---|---|---|
applicant_id | UUID | The applicant's internal ID |
external_id | string or null | Your external user identifier |
case_id | UUID | The case record ID |
case_type | string | Case category (e.g., "screening_hit", "document_review", "risk_review") |
priority | string | "low", "medium", "high", or "critical" |
reason | string | Human-readable reason for the case |
auto_created | boolean | true if system-generated, false if manually created |
created_at | ISO 8601 | When the case was created |
Session Events
session.completed
Fired when a verification session reaches a terminal state. This event is sent to the webhook_url specified when the session was created (if provided), and also through the standard tenant webhook system.
Source: backend/app/services/session.py -- _send_completion_webhook()
{
"event_type": "session.completed",
"event_id": "e1f23456-7890-1234-5678-234567890123",
"timestamp": "2026-02-04T14:15:00Z",
"tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"correlation_id": null,
"data": {
"session_id": "f2345678-9012-3456-7890-345678901234",
"applicant_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"completed_at": "2026-02-04T14:15:00Z",
"completion_data": {
"final_status": "approved",
"risk_level": "low"
}
}
}
| Field | Type | Description |
|---|---|---|
session_id | UUID | The verification session ID |
applicant_id | UUID | The associated applicant ID |
status | string | Session status at completion |
completed_at | ISO 8601 or null | When the session completed |
completion_data | object or null | Additional completion metadata |
Testing Events
test.ping
Sent when you use the "Test Webhook" button in the dashboard or call the test endpoint. Used to verify your webhook endpoint is reachable and correctly configured.
Source: backend/app/api/v1/integrations.py -- test webhook endpoint
{
"event": "test.ping",
"timestamp": "2026-02-04T14:00:00Z",
"data": {
"message": "This is a test webhook delivery from TrustGate",
"webhook_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}
Note: The test.ping event uses the legacy integrations delivery system and has a slightly different envelope structure than the primary webhook events.
Workflow Events
workflow.action.webhook
Fired by the workflow automation engine when a workflow includes a "send webhook" action step. This sends a custom webhook to a URL configured in the workflow, not to the tenant's standard webhook endpoint.
Source: backend/app/workers/workflow_actions/notification.py -- action_send_webhook()
{
"event": "workflow.action.webhook",
"timestamp": "2026-02-04T14:20:00Z",
"tenant_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"workflow_execution_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"applicant": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "approved",
"risk_level": "low"
}
}
Note: This event has a different payload structure because it is sent directly by the workflow engine, not through the standard webhook delivery service. The payload can include custom fields defined in the workflow configuration.
Delivery Headers
Every webhook delivery includes the following HTTP headers:
| Header | Description | Example |
|---|---|---|
Content-Type | Always application/json | application/json |
X-Webhook-Signature | HMAC-SHA256 signature of {timestamp}.{payload} | abc123def456... |
X-Webhook-Timestamp | Unix timestamp of the delivery (for replay protection) | 1707058800 |
X-TrustGate-Signature | GitHub-style prefixed signature | sha256=abc123def456... |
User-Agent | Identifies the sender | TrustGate-Webhook/1.0 |
Next Steps
- Webhooks -- Webhook setup, signature verification, and management
- SDK Integration -- Client SDK guide
- API Keys -- Authentication and key management