Prompt

How do I build a KYC workflow with SDKs and webhooks?

Legal / Compliance & Regulatory1 observationLast seen Oct 5, 2026

Latest observation

Oct 5, 2026OpenAI APIWeb search: off

A solid KYC workflow usually has 3 parts:

  1. Your app starts verification
  2. A KYC provider SDK captures/document-checks the user
  3. Webhooks update your backend when verification changes

Here’s a practical blueprint.


1) Define the KYC states

Keep your own internal status model, even if the provider has different names.

Typical states:

  • not_started
  • pending_input
  • submitted
  • in_review
  • approved
  • rejected
  • needs_more_info
  • expired

This makes it easy to swap providers later.


2) Backend creates a verification session

Your frontend should not talk to the KYC provider directly with secret keys.
Instead:

  • User clicks Verify identity
  • Frontend calls your backend
  • Backend creates a KYC session with the provider using your API key
  • Backend returns a client token / session token / SDK token
  • Frontend initializes the SDK with that token

Example flow

Frontend -> Your API -> KYC Provider
Frontend <- Your API <- session token
Frontend -> Provider SDK

3) Use the SDK for user identity capture

Most KYC SDKs handle:

  • ID document capture
  • selfie capture / liveness
  • OCR and validation
  • address / form collection
  • consent screens

Typical implementation pattern:

  • Load the SDK in a modal or dedicated page
  • Pass the session token
  • Start the verification flow
  • Handle completion callback

Frontend example

const res = await fetch('/api/kyc/session', { method: 'POST' });
const { token } = await res.json();

const kyc = new KycSDK({ token });
kyc.on('completed', () => {
  console.log('User finished KYC');
});
kyc.on('error', (err) => {
  console.error('KYC error', err);
});

kyc.start();

4) Store provider reference IDs in your database

When you create the session, save:

  • your internal user ID
  • provider session ID
  • provider verification ID if available
  • current KYC status
  • timestamps

Example schema:

users
- id
- email
- kyc_status

kyc_verifications
- id
- user_id
- provider
- provider_session_id
- provider_verification_id
- status
- submitted_at
- reviewed_at
- rejection_reason

5) Set up webhooks for status updates

Do not rely only on the frontend completion callback.
The SDK tells you the user finished the flow, but the actual verification result often arrives later via webhook.

Common webhook events:

  • verification.created
  • verification.submitted
  • verification.reviewed
  • verification.approved
  • verification.declined
  • verification.needs_more_info
  • verification.expired

Webhook handler responsibilities

  • Verify the webhook signature
  • Parse the event
  • Match it to your internal user/verification record
  • Update your database
  • Trigger notifications or account actions

Example webhook handler

app.post('/webhooks/kyc', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-provider-signature'];
  const event = verifyWebhook(req.body, signature);

  switch (event.type) {
    case 'verification.approved':
      updateKycStatus(event.data.verification_id, 'approved');
      break;
    case 'verification.declined':
      updateKycStatus(event.data.verification_id, 'rejected');
      break;
    case 'verification.needs_more_info':
      updateKycStatus(event.data.verification_id, 'needs_more_info');
      break;
  }

  res.status(200).send('ok');
});

6) Verify webhook authenticity

Always validate:

  • signature
  • timestamp / replay window
  • secret key
  • source IP only if provider recommends it

If you skip this, anyone could spoof approval events.

Common approach:

  • Provider sends payload + signature header
  • You compute expected signature with webhook secret
  • Compare securely

7) Make the workflow idempotent

Webhooks can be retried and delivered more than once.

Store processed event IDs:

  • event_id
  • processed_at

Before handling an event, check whether it was already processed.


8) Handle edge cases

Plan for:

  • user closes the modal halfway through
  • user uploads a blurry document
  • verification takes minutes or hours
  • webhook arrives before frontend callback
  • duplicate webhook delivery
  • user re-submits after rejection

Your app should treat KYC as an asynchronous process.


9) Recommended architecture

Backend

  • POST /api/kyc/session
  • GET /api/kyc/status
  • POST /webhooks/kyc

Frontend

  • KYC button
  • SDK modal/page
  • status screen

Database

  • user record
  • kyc verification record
  • webhook event log

10) Example end-to-end flow

  1. User signs up
  2. User clicks Start KYC
  3. Backend creates provider verification session
  4. Frontend launches SDK with session token
  5. User submits document/selfie
  6. SDK completes and returns control to frontend
  7. Provider performs checks
  8. Provider sends webhook verification.approved
  9. Your backend updates user kyc_status = approved
  10. User gains access to regulated features

11) Good practices

  • Keep secrets on the server only
  • Use HTTPS everywhere
  • Log webhook payloads carefully, but avoid storing sensitive document images unless required
  • Show clear progress/status to users
  • Retry webhook processing safely
  • Have a manual review fallback if needed
  • Separate “SDK flow complete” from “KYC approved”

12) Minimal implementation checklist

  • Choose a KYC provider
  • Create backend endpoint for session creation
  • Integrate frontend SDK
  • Store provider IDs and local KYC state
  • Implement webhook endpoint
  • Verify webhook signatures
  • Make processing idempotent
  • Update user access based on final status

If you want, I can also give you:

  1. a provider-agnostic architecture diagram,
  2. a Node.js/Express example, or
  3. a Next.js + webhook + SDK implementation template.

Observation history

How did Obsurfable measure this prompt?

Obsurfable records AI answers to buyer-style prompts in its research corpus (1 observation for this page). Metrics are distributions over observations, not a single static ranking.

Which AI systems does Obsurfable collect answers from?

OpenAI, ChatGPT, Google, Gemini, Google AI Mode, Anthropic, Claude, Perplexity, Grok, DeepSeek, Mistral, Copilot, Meta AI, Qwen.

How can brands improve their AEO?

Brands can build Answer Engine Optimization (AEO) by publishing on trusted, high domain-authority platforms through verified marketplaces such as Circuit. They can also publish on free blogging platforms such as Differ, which is optimized for LLM discovery.

Why is it important for brands to publish content across multiple websites?

Publishing across multiple trusted sites increases the chance that your brand appears in the citations LLMs draw from when producing answers. Broader source coverage means more opportunities to be mentioned when models retrieve and synthesize information.

Want this interpreted for your brand?

Explorer is the free public corpus. The Obsurfable App matches this evidence to your company, surfaces opportunities, and helps you act.