Skip to main content
Version: 1.x.x

Video KYC - React

Video KYC lets an agent verify a customer's identity over a one-to-one video call. The customer joins from a phone or a browser, presents an identity document and shows their face, the agent reviews the captured images, and the session can be recorded and transcribed for the verification record.

If you are new to VideoSDK, start with Concept and Architecture and Integrate React SDK, and check Supported Browsers.

Architecture of a video KYC deployment on VideoSDK. The customer's phone and the agent's console get tokens from your backend and exchange encrypted audio, video and data with VideoSDK. Your backend holds tokens, the queue, the verification record and captured images sent to the Identity Verification APIs and uses REST APIs and webhooks. The agent's traffic passes your firewall and an optional proxy. VideoSDK provides meeting rooms, chat, transcription, the Identity Verification APIs, recordings in your cloud storage and session-wide security controls.

note

VideoSDK runs the live video, audio, image capture, recording and identity checks for the verification call. Your application owns the queue, the scheduling, the verification case and the decision on each verification.

Set Up the KYC Session​

Prepare the room and generate participant tokens on your backend before the verification session begins.

  • Manage the queue in your backend: VideoSDK does not order or assign customers across sessions, so keep the queue in your scheduling system. Assign the next customer to an available agent, create the room when the customer reaches the front of the queue, and issue the tokens when it is their turn. Show the customer their position and estimated wait on your scheduling screen, and move them to the pre-call screen when their session is ready.
  • Create a room: Use the Create a Room API to create a room for each KYC verification session. Use the returned roomId to associate the session with the customer's verification case in your scheduling system.
  • Validate the room: Before issuing the customer's token, use the Validate a Room API to ensure the room is valid and available for the session. If validation fails, do not issue the token, and report the failure to your scheduling system.
  • Configure participant permissions: Set allow_join and allow_mod in the agent's token to let the agent join directly and request access to the customer's camera or microphone. Set ask_join in the customer's token so they wait in the lobby until the agent admits them. Include roomId and participantId in both token payloads, with version set to 2. See Authentication and Tokens.
  • Gate controls by role: Features such as image capture and recording are available to all participants by default. Show these controls only in the agent's console to keep verification actions under the agent's control.

Configure the Customer's Devices and Network​

Customers join KYC sessions from a phone or browser, often over a mobile network. Prepare their devices and assess network quality before the call, and support device and camera switching during verification.

Check Devices and Network Before the Call​

The customer's pre-call screen and the checks behind it. On the left, a phone shows a camera preview, camera and microphone selectors, a microphone test with a level meter, a speaker test with a play button, a connection line reading good connection, ready for video, and a join the call button. On the right, four cards list the checks: permissions granted, devices listed and refreshed when a headset is connected, microphone and speaker tested, and network measured with a quality score and factors, followed by a card saying the choices are carried into the meeting

  • Check permissions and devices: Provide a pre-call screen where customers can grant camera and microphone permissions, preview their camera, and test their microphone and speaker. Use checkPermissions() and requestPermission() from the useMediaDevice hook to manage permissions. Use getCameras() and getMicrophones() to list available devices, and onDeviceChanged to refresh the list when devices are connected or disconnected. See Precall Setup.
  • Assess network quality: Use runPreCallTest() to evaluate uplink and downlink quality on a scale from 1 (BAD) to 5 (EXCELLENT), along with the factors affecting each score. Use the results to select an appropriate starting media configuration and inform the customer about potential quality limitations. See Precall Setup.
  • Apply the verified setup: Pass the selected camera and microphone devices, their enabled states, and the chosen media configuration to MeetingProvider so the meeting starts with the setup the customer verified. Refer to the Precall Setup guide for recommended configurations based on the test results. The configuration can include a custom camera track created with createCameraVideoTrack(). See Optimize Video Tracks.
  • Join after pre-call checks: Set joinWithoutUserInteraction to true on MeetingProvider if your application has already collected the customer's consent to join during the pre-call flow. See Join Meeting.

Switch Devices and Cameras During Verification​

  • Allow customers to change devices: Provide in-call controls to switch microphones or cameras if a device stops working or the customer needs to change their setup. Use getMics() and getWebcams() from the useMeeting hook to list available devices and their deviceId and label. Pass the selected deviceId to changeMic() or changeWebcam(). See Change Input Device.
  • Use the appropriate camera for each verification step: The rear camera is typically better suited to capturing identity documents, while the front camera is used for face verification. Use getWebcams() to inspect each camera's facingMode, select environment for the rear camera or front for the front camera, and pass the selected deviceId to changeWebcam(). The agent can prompt the customer to switch cameras over PubSub. See Switch Remote Participant Camera and Change Input Device.

Configure the Agent's Verification Console​

The agent conducts the KYC verification from a console, guiding the customer through identity document capture, face verification, and media checks. The console should provide controls for admitting the customer, requesting captures, reviewing verification results, and controlling the call.

Two screens side by side. On the left, the customer's phone shows the rear camera with a dashed frame reading align your ID inside the frame, a chat message from the agent reading hold the card a little closer, a recording indicator, and microphone, switch camera and camera buttons. On the right, the agent's console shows the customer's video tile with a recording badge, a capture ID button, a switch to face button, a captured documents panel with an ID front image and a selfie marked received, a checks panel listing face match, spoof detection and number of faces, and a chat panel

Prepare the Agent's Environment Before the Call​

  • Check devices and network: Have the agent complete the pre-call checks, including runPreCallTest(), before admitting the customer. This helps identify device or connectivity issues before verification begins. See Precall Setup.
  • Apply a virtual background: Use the Virtual Background plugin to blur or replace the agent's background. Apply the effect only to the agent's camera so it does not alter the customer's document or face images. Virtual backgrounds are supported on desktop browsers.
  • Suppress background noise: Use the Noise Suppression plugin on the agent's microphone to reduce background noise and help the customer hear verification instructions clearly.

Admit the Customer from the Lobby​

note

The waiting lobby only holds the customer until the agent admits them. Your system is responsible for the queue of customers, as described in Set Up the KYC Session.

  • Admit the customer: When the customer joins with an ask_join token, they wait in the lobby until the agent admits them. Handle onEntryRequested in the agent's console to receive the customer's participantId and name, then call allow() to admit them. Both participants receive onEntryResponded with the admission decision. See Waiting Lobby.
  • Handle a denied request: If the agent denies the request, display an appropriate message to the customer. Call leave() in the customer's application to disconnect them, since they remain connected until your application does so, then return them to the scheduling screen. See Leave or End Meeting.

Capture Identity Documents Remotely​

Capture images from the customer's local camera rather than extracting them from the remote video stream in the agent's console. A remote stream may use a lower-resolution video layer, particularly under limited bandwidth, while a local capture can provide a more suitable image for verification.

The agent requests a capture, the customer's application captures the image using captureImage(), and the image is sent to the agent through PubSub.

A sequence diagram with three lifelines: the agent's application, VideoSDK PubSub, and the customer's application. Step one, the agent publishes a capture request addressed only to the customer. Step two, the customer's application calls captureImage on its own camera. Step three, the customer's application splits the Base64 image into chunks and publishes each chunk addressed only to the agent, with a transfer ID, chunk index and total count in the payload. Step four, the agent's application reassembles the chunks in order, displays the image and saves it

StepRuns onWhat happens
1. Request the captureAgent's applicationPublish a capture request on a PubSub topic using publish(). Set the customer's participantId in sendOnly so only the customer receives the request. See PubSub Overview.
2. Capture the imageCustomer's applicationUse captureImage() from the useParticipant hook for the local participant to capture an image as a Base64 string. Pass width and height when a smaller image is sufficient for verification. See Image Capturer.
3. Send the imageCustomer's applicationPublish the Base64 image to the agent on a separate PubSub topic, again using sendOnly. Decide the chunk size based on the image size and split the image into chunks. Include a transfer ID, chunk index, and total chunk count in each message's payload. See Optimize for Low Bandwidth Networks.
4. Reassemble and reviewAgent's applicationGroup chunks by transfer ID, reassemble them in index order after all chunks arrive, and validate the result before use. Discard incomplete transfers rather than treating a partial image as a document. Display the completed image in the console for review and save it in your own storage as part of the verification record.
note

Set persist to false when publishing capture requests and image chunks so the image data is not retained in the session's message history. Store the reassembled image in your own system and apply appropriate access controls and retention policies.

Verify the Captured Images​

Use the Identity Verification APIs from your backend to extract document details and evaluate face verification checks. Each API accepts an image as a Base64 string with the data:image/jpeg;base64, prefix, as returned by captureImage().

APIPurpose
OCR APIExtracts text and fields from the front or back of an identity document.
Face Match APICompares the face in the document image with a separately captured face image and reports whether they match.
Face Spoof Detection APIEvaluates a face image for signs of spoofing and returns a spoof flag.
Number of Face Detection APIDetects the number of faces present in an image.

Use the results as inputs to your verification workflow. Your application applies its own rules to decide whether the verification passes, fails or needs a manual review.

Control the Call​

  • Request access to the customer's media: Use enableWebcam() or enableMic() from the useParticipant hook to request camera or microphone access. Handle onWebcamRequested or onMicRequested in the customer's application so the customer can accept or decline the request. See Toggle Remote Participant Media.
  • Prompt a camera switch: Use publish() on a PubSub topic addressed to the customer, with front or back as the value, to ask the customer's application to switch to the rear camera for the document or the front camera for the face. Handle the message in the customer's application by selecting the camera with the matching facingMode and passing its deviceId to changeWebcam(). See Switch Remote Participant Camera.
  • Guide the customer through chat: Use PubSub to send instructions such as asking the customer to hold their identity document closer to the camera. Set persist to true if messages should remain in the session's message history. Persisted messages can be downloaded as CSV from the VideoSDK session dashboard for the audit record. See Chat using PubSub.
  • End the session: Call end() from the useMeeting hook when verification is complete to end the meeting for all participants. See Leave or End Meeting.

Configure the Call Screen on Both Sides​

These components are built into both the customer's application and the agent's console.

Display the Verification Call​

  • Render each participant's video: Use the VideoPlayer component to render each participant's video. It requests the video quality that matches the tile size, so the customer's document and face appear large and clear on the agent's screen and the agent fills the customer's phone, and it mirrors the local preview. See Display Audio and Video.

Control Your Own Media​

Show Participant Status​

  • Track participant joins and leaves: Use onParticipantJoined and onParticipantLeft from the useMeeting hook to update each screen when the other participant joins or disconnects. See Participant Events.
  • Show microphone and camera status: Use micOn and webcamOn from the useParticipant hook to indicate whether the other participant's microphone and camera are enabled. See Display Audio and Video.
  • Monitor the incoming video stream: Use onStreamStateChanged from the useStream hook to detect when the other participant's video stream becomes active, stuck, or frozen, so each side can ask the other to check their connection before continuing. See Monitoring Remote Streams.

Keep the Session Reliable​

These controls apply to both the customer's application and the agent's console.

Handle Network Changes During Verification​

Network conditions can change during a verification call. Customers may use mobile networks, while agents may connect through corporate or shared office networks. VideoSDK adapts video quality to available bandwidth and provides network and media events that help your application respond to changing conditions.

  • Keep both sides informed: Use the relevant quality events to notify the customer and the agent when network conditions affect call quality and when conditions improve. See Monitoring Network Quality for available events and Optimize for Low Bandwidth Networks for recommendations before and during the call.
  • Show the connection state: Use onMeetingStateChanged from the useMeeting hook to follow the meeting connection through CONNECTING, CONNECTED, RECONNECTING and DISCONNECTED. Show a reconnecting indicator on both screens while the state is RECONNECTING, so the customer and the agent know the verification is recovering rather than over, and return to your scheduling screen when it reaches DISCONNECTED. See Meeting Connection State Events.
  • Handle image transfer failures: Capturing an image locally is separate from transmitting the video stream, but sending the image to the agent requires a working network connection. Show a pending state while the image is being transferred. Set a timeout and display an error if the transfer does not complete. Allow the agent to retry the transfer or request a new capture, and confirm that the complete image has been received and validated before proceeding with verification.

Detect a Silent Microphone​

  • Warn when the microphone stops capturing audio: A customer's microphone can go silent while it is still on, for example when they answer a phone call in a mobile browser or another application takes over the microphone. Use onAudioInputSilence from the useMeeting hook to detect this on the customer's device and show them a warning to check their microphone. Since the event is only raised on the customer's own device, publish() the detected and resolved states to the agent over PubSub so the console can indicate that the customer cannot be heard. Remove the warning when the event reports resolved or the customer turns the microphone off. See Audio Input Silence Events.

Handle Errors and Follow Best Practices​

  • Handle SDK errors: Use onError from the useMeeting hook to receive error information when a meeting operation fails. Display actionable feedback in the customer's application and the agent's console, and send relevant diagnostic details to your monitoring service so failures across verifications stay visible to your team. Avoid including sensitive verification data in logs. See Error Events.
  • Follow integration guidelines: Review the User Experience Guidelines and Developer Experience Guidelines to build a reliable, accessible verification experience.

Recording​

Configure recording, storage delivery, and encryption based on your verification requirements. You can start recording when the customer is admitted and configure location tagging and transcription alongside it. If recording is mandatory, verify that it has started before proceeding with verification. The recording's delivery destination and encryption depend on your configured storage and encryption settings.

Choose the Recording Type​

VideoSDK offers three types of recording. Choose the one that matches what your verification record needs. See Recording Overview.

note

Geo tagging uses a custom recording template, which only the meeting (composite) recording supports. Use the meeting recording when you need the location watermark.

Record the Session for Audit​

  • Start recording automatically: If the session must be recorded from the beginning, show the customer a consent notice before the call, then add a recording entry to autoStartConfig when creating the room with the Create a Room API. Use this entry to configure transcription, recording config, and the geo-tag templateUrl as needed. See Create a Room.
  • Wait for recording confirmation: Show a loader on both screens until the recording starts. The backend receives the recording-started webhook, while the applications receive onRecordingStateChanged with RECORDING_STARTED. If the agent starts recording manually using startRecording() from the useMeeting hook, show the same loader until the started status arrives. See Start and Stop and Webhook and Events.
  • Handle recording failures: VideoSDK sends the recording-failed webhook if recording fails while starting, during the call, or while stopping. If recording fails at the start and recording is mandatory, do not proceed with the verification. If recording is optional, you can continue without it. If recording fails during the call, you can retry or end the session. To close the room automatically when recording fails, configure the onFailure option as described below. See Recording Failed Webhook.
  • Close the room automatically: If recording is mandatory, configure VideoSDK to close the room when recording fails. Add an onFailure entry to the recording section of autoStartConfig, or include it in the request body when starting recording from your backend. Set action to close-room and configure waitTime in seconds. We recommend 30 seconds. See the onFailure parameter and example request body in Create a Room and Start Recording.
  • Stop the recording and store the file: The recording stops automatically when the session ends. To stop it earlier, call stopRecording() from the useMeeting hook or the Stop Recording API from your backend. Your backend receives the recording-stopped webhook with the fileUrl, filePath and sessionId, so it can attach the file to the verification record. To look the file up later, use the Fetch Recordings API to list the recordings of a room or the Fetch a Recording API to retrieve one by its id. See Webhook and Events.

Store Recordings in Your Own Storage​

  • Configure your own storage: Use Configure Recording Storage in the dashboard to deliver recordings to your own AWS S3, Azure Blob or GCP bucket. It is set per API key and includes a test step.
  • Upload with a presigned URL: When stored credentials are not allowed, generate a presigned URL on your backend and pass it to the Start Recording API, so the recording is uploaded to one object for a limited time.
note

VideoSDK uploads recordings to your storage with the credentials you set up. If your storage only accepts uploads from approved IP addresses, you will need to approve VideoSDK's static IP addresses. Contact us to request them.

Encrypt and Decrypt Recordings​

  • Encrypt recordings at rest: Turn on Recording Encryption for the API key in the dashboard, under Cloud Storage Configuration, and provide an RSA public key. Each recording is encrypted with its own AES key before upload. AES-256-GCM is recommended.
  • Decrypt with your private key: Each recording arrives as three files: the encrypted recording, the wrapped AES key and a metadata file. Decrypt them on your side with your private key. The guide includes a Node.js example.
note

Recording Encryption and transcription cannot be enabled together on one API key, since transcription runs on unencrypted recordings. Decide per API key which your verification record needs before configuring either.

Geo Tag the Recording​

  • Add the customer's location: Use VideoSDK's recording template, which renders coordinates as a watermark. Host the template, start the recording with its URL through the Start Recording API, and publish the customer's latitude, longitude and participantName on the GEO_TAG topic. The watermark shows the coordinates your application supplied and is not independent proof of location. See Geo Tag Recording.

Transcription​

Live captions help agents confirm customer responses during verification, while post-call transcripts and summaries make sessions easier to review. Transcription is not available for an API key with Recording Encryption enabled.

Show Live Captions​

Generate the Transcript and Summary​

Choose the Language​

  • Set the spoken language: Pass the appropriate language code to startTranscription(). The default is en. See Supported Languages for available codes, including regional variants such as en-IN, hi, and es-419.
  • Translate captions when needed: If the agent and customer speak different languages, use Realtime Translation to help both sides follow the conversation.

Meet Compliance Requirements​

Configure these session-wide controls to align your verification workflow with your organization's data protection policies and regional requirements.

RequirementControl
Keep media within a regionUse Geo Fencing to restrict connections to VideoSDK servers in your specified regions, regardless of the customer's location. See Geo Fencing.
Allow or restrict access by locationUse Geo IP Restriction to allow or deny access based on the customer's IP address and your geographic rules. See Geo IP Restriction.
Encrypt media end to endUse E2EE to encrypt media on the sender's device and decrypt it only on the receiver's device, preventing intermediaries, including VideoSDK servers, from accessing the media. Your application is responsible for generating and distributing encryption keys. See E2EE Setup.
Meet regulatory requirementsVideoSDK offers compliance programs that a bank's vendor review typically asks for: CERT-IN for deployments in India, ISO 27001, SOC 2 Type II and GDPR, including a Data Processing Agreement. GDPR compliance and the Data Processing Agreement are available as add-ons.
note

If E2EE is enabled and you want to record or transcribe the session, use a custom recording template. See Customize Recording UI.

  • Recording: Build the template with the React or JavaScript SDK and enable E2EE in it using the same key provider and shared key as your application, so the template can decrypt the media for recording. Deliver the key securely from your backend to the template over HTTPS rather than including it in the templateUrl, then start the recording using the template's templateUrl.
  • Transcription: Use the same template recording for the post-call transcript and summary, since post transcription runs on the recording file. Realtime transcription is not available when E2EE is enabled.

Firewall and Debugging​

Agents often connect from corporate networks, and some customers may use restricted networks as well. Configure firewall rules before the first verification session to ensure the required VideoSDK services are reachable. If a session fails to connect, use the checks below to identify potential network restrictions.

Allow VideoSDK Traffic Through Your Firewall​

  • Allow VideoSDK domains: The simplest approach is to allow all subdomains of *.videosdk.live over TCP and UDP on all ports. This covers the API, signaling, media, and TURN servers. See Firewall Setup.

  • Allow specific hosts and ports: If your network policy requires explicit firewall rules, allow the following hosts and ports. VideoSDK can use the fallback transport when the primary connection is unavailable.

    ServerHostPrimaryFallback
    APIapi.videosdk.liveTCP 443—
    Signaling*.rm.videosdk.live, or the regional hosts listed in the Firewall Setup guideTCP 443—
    Mediamedia.videosdk.liveUDP 40000–60000TCP 40000–60000
    TURNturn.videosdk.liveUDP and TCP 3478TCP 443

    Also allow sdk.videosdk.live over TCP 443 if your console loads the SDK or the PubSub worker from the VideoSDK CDN. The full-access policy already covers it.

  • Allow the PubSub worker in your Content Security Policy: PubSub runs in a web worker created from a blob: URL. If the agent console runs under a strict Content Security Policy, allow blob: in the worker-src directive, or pass pubsubWorkerUrl to MeetingProvider to load a pre-built worker from the VideoSDK CDN or your own domain. See CSP policy for PubSub.

  • Use Cloud Proxy for restricted networks: If the required ports cannot be opened, use Cloud Proxy to route media through the proxy servers you specify. Choose UDP over TCP (the default), Force UDP, or Force TCP according to your network restrictions.

Debug Connection Issues​

  • Test the network before the first session: Run runPreCallTest() from the agent's network after configuring the firewall. The test checks whether a call can transmit media in both directions. If it fails despite internet access, review the required hosts and ports above. See Precall Setup.
  • Check UDP connectivity: Set preferredProtocol to TCP_ONLY in MeetingProvider and try connecting again. If the call succeeds over TCP but fails with the default UDP_OVER_TCP configuration, investigate whether UDP traffic is blocked on the media or TURN ports. You can also configure Cloud Proxy for the affected network.
  • Inspect connection errors: Use onError from the useMeeting hook to capture the error code and message when a connection fails. Use this information to investigate whether the failure occurred during the API, signaling, or media stage, and forward relevant diagnostics to your monitoring service to identify affected networks. See Error Events.
  • Verify media flow: Use getTransportStats() from the useParticipant hook to inspect transport statistics and check whether traffic is flowing in both directions. If one direction shows no bitrate, investigate the corresponding network path and firewall rules. See Monitoring Transport Stats.
  • Collect connection logs: Call setLogLevel() with Constants.LogLevel.DEBUG to collect detailed diagnostics while reproducing the issue. After troubleshooting, restore the log level to INFO or NONE as appropriate. See Log Level.

API Reference​

The API references for all the methods and events utilized in this guide are provided below.

Got a Question? Ask us on discord