Overview
KYC (Know Your Customer) webhook events allow you to receive real-time notifications when a KYC verification status changes. Gu1 automatically sends HTTP POST requests to your configured webhook endpoint whenever a validation status updates, enabling you to automate customer onboarding workflows and maintain compliance.Why Use KYC Webhooks?
Real-Time Updates
Get instant notifications when verification status changes
Efficient
No need to poll the API repeatedly
Automated Workflows
Automatically update user accounts based on verification results
Better UX
Notify customers immediately after verification
Available Events
Gu1 sends webhooks for the following KYC validation events:| Event Type | Description | When Triggered |
|---|---|---|
kyc.validation_created | Validation session created | When you create a new KYC validation |
kyc.validation_in_progress | Customer started verification | Customer is actively completing verification (filling out form) |
kyc.validation_in_review | Verification under review | Verification completed, requires manual review from compliance team |
kyc.validation_approved | Verification approved | Identity successfully verified |
kyc.validation_rejected | Verification rejected | Identity verification failed |
kyc.validation_abandoned | Customer abandoned process | Customer left without completing |
kyc.validation_expired | Validation session expired | Session expired (typically after 7 days) |
kyc.validation_cancelled | Validation cancelled | Validation manually cancelled by organization |
Event Payload Structure
Every KYC webhook uses the same outer envelope. The innerpayload object is the KYC validation row as stored in Gu1 (same field names as in the database/API: id is the validation UUID, plus entityId, organizationId, status, decision, extractedData, verifiedFields, warnings, metadata, timestamps, etc.).
entity (full Gu1 entity row) is sent only for terminal outcomes: kyc.validation_approved and kyc.validation_rejected. It is not included for kyc.validation_created, in_progress, in_review, abandoned, expired, or cancelled. This is an additive field: all previous payload fields are unchanged. For kyc.validation_approved, optional person auto-population from KYC still runs after the webhook (same order as before); payload.entity is a snapshot at webhook send time (before that step). To read the entity after auto-population, call the Entities API.payload.entity includes all entity columns, JSON-serializable, with dates as ISO strings (entityData, attributes, email, phone, etc.).
Common Payload Fields
The event type (e.g.,
kyc.validation_approved)ISO 8601 timestamp when the event occurred
Your organization ID
The KYC validation ID in Gu1 (primary key of the validation row)
The entity (person) ID being verified
Present only for
kyc.validation_approved and kyc.validation_rejected. Snapshot of the entity row in Gu1 at webhook send time (on approve, before optional auto-population runs).Current validation status:
pending, in_progress, in_review, approved, rejected, abandoned, expired, cancelledDecision object (payload.decision)
When a validation reaches a terminal or in-review state with provider results, payload.decision contains the full verification outcome from the KYC flow. Gu1 always stores and returns both shapes for each feature: a singular object (legacy) and a one-element array (current). You can read either id_verification or id_verifications[0]; they are kept in sync. The same applies to liveness / liveness_checks, face_match / face_matches, aml_screening / aml_screenings, and ip_analysis / ip_analyses.
Media fields (front_image, reference_image, images.*, etc.) are Gu1 storage keys (kyc/...) after ingest. Fetch them via the validation media API. Older rows may still contain short-lived HTTPS URLs until synced.
Approved example (complete):
Event-Specific Payloads
kyc.validation_created
Sent when a new KYC validation is created. Thepayload is the validation row; entity is not included (non-terminal event).
kyc.validation_in_progress
Sent when a customer starts the verification process.entity is not included.
kyc.validation_in_review
Sent when a customer completes verification and requires manual review from the compliance team.entity is not included.
kyc.validation_approved
Sent when verification is successfully completed.entity is included (full row at send time; optional auto-population may run afterward, same as before).
entity: Full Gu1 entity record at send time (all columns; dates as ISO strings)verifiedAt: Timestamp when verification was approvedextractedData: Personal information extracted from the documentverifiedFields: Array of fields that were successfully verifiedwarnings: Array of any warnings detected during verification (empty if approved)decision: Verification results for each check
kyc.validation_rejected
Sent when verification fails.entity is included (current entity row in Gu1; typically unchanged by KYC on rejection).
entity: Full Gu1 entity record at send timewarnings: Array of reasons why verification failedrejectionReason: Primary reason for rejection
kyc.validation_abandoned
Sent when a customer starts but doesnβt complete the verification.entity is not included.
lastStep: The last step the customer completed before abandoning
kyc.validation_expired
Sent when a validation session expires without completion.entity is not included.
kyc.validation_cancelled
Sent when a validation is manually cancelled by the organization.entity is not included.
Code Examples
Node.js - Handling KYC Events
Python - Handling KYC Events
Use Cases
Use Case 1: Automatic Account Activation
Automatically activate customer accounts when KYC is approved:Use Case 2: Compliance Monitoring
Track KYC rejections for compliance review:Use Case 3: Abandoned Verification Recovery
Send reminders to customers who abandon verification:Best Practices
Use entity.externalId for Lookup (terminal events)
Use entity.externalId for Lookup (terminal events)
For For other KYC events, use
kyc.validation_approved and kyc.validation_rejected, payload.entity includes the full entity rowβuse entity.externalId to match the record you created in Gu1.payload.entityId (and your own mapping) until you receive a terminal event.Store Validation IDs
Store Validation IDs
Store the validation UUID from Gu1 (
payload.id) in your database so you can query validation details later.Handle Idempotency
Handle Idempotency
You might receive the same webhook multiple times. Use
payload.id and the event type to deduplicate.Return 200 Quickly
Return 200 Quickly
Always return a 200 status code as quickly as possible to acknowledge receipt. Process the webhook asynchronously if needed.
Verify Signatures
Verify Signatures
Always verify the
X-Webhook-Signature header to ensure the webhook is authentic. See the security guide for details.Handle Errors Gracefully
Handle Errors Gracefully
If processing fails, log the error but still return 200 to prevent retries. Store failed webhooks for manual review.
Troubleshooting
Not Receiving Webhooks
Not Receiving Webhooks
Check these items:
- Webhook URL is publicly accessible via HTTPS
- Webhook is configured and enabled in dashboard
- Subscribed to correct KYC event types
- Endpoint returns 200 status code within 30 seconds
- Check server logs for incoming requests
Missing extractedData
Missing extractedData
extractedData and verifiedFields are only included in:kyc.validation_approvedkyc.validation_rejected
validation_created or validation_in_progress.Signature Verification Failing
Signature Verification Failing
Common causes:
- Using wrong secret (check dashboard for current secret)
- Verifying signature on parsed JSON instead of raw body
- Re-verifying from Webhook Monitor JSON (pretty-print /
JSON.stringifyβ signed bytes) - Middleware that mutates the body before verification (some payloads fail, others pass)
- Secret not properly saved after webhook creation
- Encoding issues (ensure UTF-8)
Receiving Duplicate Webhooks
Receiving Duplicate Webhooks
This is normal behavior. Webhooks may be sent multiple times due to network issues, timeouts, or retries.Always implement idempotency using the webhook
payload.id (validation UUID) and event type.Next Steps
Entity Events
Handle entity lifecycle events
Rule Events
Process compliance rule triggers
Webhook Security
Secure your webhook endpoints
Configuration
Configure webhook settings