Skip to content
Last updated

Form integration

A form in Kycaid is a widget designed for seamless integration into your services, supporting KYC (Know Your Customer) and KYB (Know Your Business) processes, such as user identification via document uploads or video interviews.

Getting an ID of a form

An ID of a form (referred to as form_id in our system) is a unique identifier assigned by our system when a form is created. This ID is generated in a 36-characters UUID-like format (e.g., 27c5caea93ee4656881ef9a30fadd21a3768).

Creating a form

If you have not created a form yet, you have to create one. Log in to the Dashboard, navigate to the Forms page, and click Create new. Enter a name for the form and click Save changes.

To retrieve a form_id, go to the Forms page and click Copy in the Form ID column while hovering over the target form ID:

Highlighted location of the “Copy” icon button

Getting a form URL

From the Dashboard

To obtain the form URL from the Dashboard, click the Link button:

Highlighted location of the “Link” icon button

Then, click the Generate link in the modal window that appears:

Highlighted location of the “Generate link” primary button in the modal window

After the link is generated, you can copy it or open it in a new tab.

Highlighted location of the form URL, together with the “Run” and the “Copy URL” buttons

Using the API

To retrieve a one-time URL for a form using the API, use the Retrieve form URL API request with the form_id, which you can obtain by following the instructions in the previous section.

One form, multiple URLs

You don’t need to create a new form for every verification. Instead, you can retrieve a unique one-time URL for each user.

For new users

If a user does not have a corresponding applicant in our system, an applicant will be created after the user completes their first form and submits it for verification. Alternatively, you can create an applicant in advance using the Create an applicant object API request.

For users with created applicants

If a user has already submitted a form and you need to provide them with another verification attempt, use the Retrieve form URL API request with applicant_id of their applicant.

Avoid creating duplicates

If an applicant_id of an applicant was not used, a duplicate applicant will be created, potentially breaking the connection between applicants and verifications, and hindering versioning consistency.

Linking applicants to users in your system

When making the Retrieve form URL API request, you can include a user identifier from your system (e.g. user_id) with the external_applicant_id parameter. This ensures consistency across the whole user verification process and allows you to track your users at each step.

Providing a form to a user

You can provide users with a form using the following methods:

  • A direct URL to a form (obtained via the instructions in the previous section).
  • Embedding a form in an iframe within a browser.
  • Displaying the form using a native WebView on iOS or Android devices.

For the iframe and native WebView, there are additional settings available, that are listed below.

Custom domain name for a form

See Set up a custom domain name article for instructions on configuring a custom domain name for your forms.

Form display settings

Container sizing

For the form to display correctly on mobile screen sizes, use the following minimum container dimensions. A minimum height is required for each corresponding width.

WidthMinimum height
320 px700 px
375 px715 px
425 px775 px
500 px835 px
600 px950 px
700 px1060 px
767 px1135 px

Default form language

By default, our system sets the form language based on the locale of the user’s browser. However, you can override this using the lang query parameter. In the following example: https://forms.kycaid.com/bb37acef06fb4113a9420d65a747300e4023/?lang=en the default form language is set to English (en).

Supported languages

For the list of supported language codes, see the Get languages request.

Embedding

iframe

When using the iframe solution, the form communicates with the parent page via cross-origin postMessage events. These events report the content height of the form and the completion of the verification.

Permissions

To ensure proper microphone and camera within the iframe, permissions must be granted at both the server level (via HTTP header) and the browser level (via HTML attributes):

  • Server-side: your web server must include the Permissions-Policy header in the reponse for the page that hosts the iframe. This tells the browser that your site is authorised to share hardware access with Kycaid.
Permissions-Policy: camera=(self "https://forms.kycaid.com"), microphone=(self "https://forms.kycaid.com")
  • Client-side: you must also explicitly delegate these permissions to the iframe element using the allow attribute in your HTML code:
<iframe allow="microphone *;camera *;midi *;encrypted-media *;clipboard-read;clipboard-write;"></iframe>
Automatic resizing

The iframe resizer script adjusts the height of the iframe to match the height of the form content. This prevents internal scrollbars and empty space inside the iframe.

Include the helper script. Load the script on the parent page (the page that hosts the iframe). Place this tag inside <head>:

<script src="https://forms.kycaid.com/scripts/iframe-resizer.min.js"></script>

Initialise the resizer. Pass the ID of your iframe to the start() method. You can use any ID, but it must be the same in the id attribute and in the start() call.

HTML example:

<iframe id="kycaid-verification-form" src="https://forms.kycaid.com/<form-id>" width="100%" frameborder="0"></iframe>

JavaScript example:

// Initialise the resizer with the ID of the iframe above
window.kycaid.iframeResizer.start('kycaid-verification-form');

Stop the resizer (optional). If you remove the iframe from the DOM or navigate away from the verification, stop the resizer to free up browser resources:

window.kycaid.iframeResizer.stop();

How it works:

  • Handshake: When you call start(), the parent page starts to listen for height data from the Kycaid form.
  • Dynamic calculation: When the content inside the iframe changes (for example, a new verification step appears), the form calculates the new height.
  • Automatic update: The helper script receives the height and updates the CSS height property of the <iframe> element.

Best practices:

  • Set width to 100%: Set width="100%" on the iframe so that it stays responsive on mobile devices. The script controls only the height.
  • Wait for DOM load: Call start() after the iframe exists in the DOM. In React or Vue, call it inside useEffect or the mounted hook.
  • No manual overrides: Do not set a fixed height for the iframe in CSS. A fixed height can conflict with the script.
Manual resizing

Use these messages if you handle resizing yourself instead of using the iframe resizer script.

INITIATE_IFRAME_RESIZE is sent by the parent page to the iframe. It triggers a manual recalculation of the form content size. This should be sent once the parent page has fully loaded.

{
  "event": "INITIATE_IFRAME_RESIZE"
}

IFRAME_RESIZED is sent by the iframe to the parent page whenever the content height of the form changes.

{
  "event": "IFRAME_RESIZED",
  "width": "[...]",
  "height": "[...]"
}
Events

FORM_COMPLETED is sent by the iframe to the parent page when the applicant successfully completes the form.

{
  "event": "FORM_COMPLETED",
  "applicant_id": "[...]",
  "verification_id": "[...]"
}

iOS WKWebView

Set the allowsInlineMediaPlayback parameter to true to enable proper camera functionality.

Note that the WKWebViewConfiguration should only be used during the first initialisation of the WebView and can’t be changed afterward.

Getting verification status

Using the cross-origin postMessage event

When a user submits a completed form in an iframe, the form triggers a cross-origin postMessage event:

{
  "event": "FORM_COMPLETED",
  "applicant_id": "[...]",
  "verification_id": "[...]"
}

This allows your system to handle the form completion event programmatically.

Using the Verification completed callback

Our server provides the results of the user verification check by sending the Verification completed callback in JSON format to the URL specified in the form settings:

Highlighted location of the “The URL on which result of verification will come” block

The verification process may take anywhere from 10 seconds to 15 minutes, depending on various factors. It is important to store applicant_id and verification_id from the callback for future operations related to the applicant and verification.

Using the Verification status changed callback

To additionally track when a user completes and submits a form, enable the Send the callback when verification is created option (disabled by default) in the form settings:

Highlighted location of the “Send the callback when verification is created” block

Once enabled, our server will send the Verification status changed callback in JSON format to your server (to the same URL specified in the form settings as for Verification completed callback) when a user submits a form for verification.

Responding to a callback

After sending a callback, our server waits for a 200 HTTP response (with any response body) from your server to confirm successful delivery. If your server does not respond within 10 seconds, another callback is sent 1 minute later, with subsequent retries at these intervals:

  • 5 minutes
  • 10 minutes
  • 30 minutes
  • 1 hour
  • 3 hours
  • 6 hours
  • 12 hours
  • 24 hours.
Controlling restart

To prevent a user from restarting a form after submission, you can disable the button used to open the form upon receiving the Verification status changed callback. Optionally, re-enable it after receiving the Verification completed callback if you want the user to make another verification attempt.

Using API

You can retrieve information about the verification process by making different API requests:

Understanding verification results

There are three status levels:

  1. The highest level is the verified property of a verification, which defines the overall verification status. This property can be retrieved using the Get a verification API. The verified property may have one of the following values:
  • null: the applicant is under verification,
  • true: the applicant has passed verification,
  • false: the applicant has failed verification
  1. A lower, more specific level is the verifications.{verification_type}.verified property of a verification, which indicates the verification result for the specific verification type. Here, {verification_type} can be one of the following:
  • profile
  • document
  • facial
  • address
  • aml
  • financial
  • payment_method
  • tax_id
  • database_screening
  • company

verifications.{verification_type}.verified can have one of the following values:

  • true: a verification has passed for that specific type
  • false: a verification failed for the specific type
  1. The lowest and most specific level is the decline_reasons property of an applicant, which provides detailed reasons for a failed verification. This property can be retrieved using the Get an applicant API. The decline_reasons property lists specific causes that led to the verification failure, offering deeper insights for troubleshooting and resolution. For a detailed list of possible reasons and their descriptions, refer to the Decline reasons article.

Additional verification attempts

If a user fails the verification process and you want to allow another attempt, generate a new URL for the form (see Getting a form URL section) using the applicant_id from the Verification completed callback. This ensures that our system maintains the connection between data from multiple verifications of the user.