Skip to main content

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 Payload Structure

Every KYC webhook uses the same outer envelope. The inner payload 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.).
payload.entity is a preview only β€” a compact snapshot for routing and UX (identity fields, riskScore, attributes, and entityData.person / entityData.company). It is not the canonical entity record and may omit columns or diverge after later updates (for example optional person auto-population on kyc.validation_approved runs after this webhook). If you need the exact current entity, call the Entities API with payload.entityId (or payload.entity.id). Included on all KYC validation events when the entity exists.
payload.entity is a preview (not the full entity). Dates are ISO strings when present.

Common Payload Fields

string
The event type (e.g., kyc.validation_approved)
string
ISO 8601 timestamp when the event occurred
string
Your organization ID
string
The KYC validation ID in Gu1 (primary key of the validation row)
string
The entity (person) ID being verified
object
Preview only at webhook send time (id, externalId, name, type, taxId, countryCode, nationality, email, phone, status, riskScore, isClient, attributes, entityData.person / entityData.company, optional createdAt / updatedAt). Do not treat this as the authoritative entity signature β€” fetch the entity via the Entities API when you need the exact current record. Included for all KYC validation events when the entity exists.
string
Current validation status: pending, in_progress, in_review, approved, rejected, abandoned, expired, cancelled

Decision 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):
Rejected example (complete):

Event-Specific Payloads

kyc.validation_created

Sent when a new KYC validation is created. The payload is the validation row; entity is included.
Use case: Send the validation URL to your customer via email or SMS.

kyc.validation_in_progress

Sent when a customer starts the verification process. entity is included.
Use case: Update UI to show β€œVerification in progress” status.

kyc.validation_in_review

Sent when a customer completes verification and requires manual review from the compliance team. entity is included.
Use case: Notify compliance team for manual review. Update UI to show β€œUnder review by compliance team”.

kyc.validation_approved

Sent when verification is successfully completed. entity is included as a preview at send time (optional auto-population may run afterward; fetch the entity if you need the exact current record).
Additional Fields:
  • entity: Entity preview at send time (identity, riskScore, attributes, entityData.person/company)
  • verifiedAt: Timestamp when verification was approved
  • extractedData: Personal information extracted from the document
  • verifiedFields: Array of fields that were successfully verified
  • warnings: Array of any warnings detected during verification (empty if approved)
  • decision: Verification results for each check
Use case: Activate customer account and grant access to services.

kyc.validation_rejected

Sent when verification fails. entity is included as a preview (typically unchanged by KYC on rejection; fetch the entity if you need the exact current record).
Additional Fields:
  • entity: Entity preview at send time
  • warnings: Array of reasons why verification failed
  • rejectionReason: Primary reason for rejection
Use case: Notify customer that verification failed and provide guidance on next steps.

kyc.validation_abandoned

Sent when a customer starts but doesn’t complete the verification. entity is included.
Additional Fields:
  • lastStep: The last step the customer completed before abandoning
Use case: Send a reminder email to complete verification.

kyc.validation_expired

Sent when a validation session expires without completion. entity is included.
Use case: Clean up pending validations and notify customer to restart verification.

kyc.validation_cancelled

Sent when a validation is manually cancelled by the organization. entity is included.
Use case: Notify customer that validation was cancelled. Clean up associated resources and update status in your system.

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

For 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.
For other KYC events, use payload.entityId (and your own mapping) until you receive a terminal event.
Store the validation UUID from Gu1 (payload.id) in your database so you can query validation details later.
You might receive the same webhook multiple times. Use payload.id and the event type to deduplicate.
Always return a 200 status code as quickly as possible to acknowledge receipt. Process the webhook asynchronously if needed.
Always verify the X-Webhook-Signature header to ensure the webhook is authentic. See the security guide for details.
If processing fails, log the error but still return 200 to prevent retries. Store failed webhooks for manual review.

Troubleshooting

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
extractedData and verifiedFields are only included in:
  • kyc.validation_approved
  • kyc.validation_rejected
They are not present in other event types like validation_created or validation_in_progress.
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)
See Webhook Security β€” especially Raw body vs parsed JSON, Webhook history in the dashboard, and Intermittent signature failures.
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