Skip to main content

Waterfall flow

Age verification with k-ID is a privacy-preserving process that allows users to prove their age without revealing personal information. This approach uses a Waterfall flow model.

Waterfall flow

AgeKit+ acts as a single-point orchestrator for age checks, automatically cascading through a waterfall of verification providers to confirm a user's age. In practice, one API call to k-ID presents the configured methods in sequence. For example, starting with email inference or a facial age estimation and then falling back to an ID document scan or other methods as needed, until the user's age is verified or all options are exhausted. This means developers integrate once with k-ID's API, and the platform handles trying multiple verification techniques behind the scenes, combining methods to maximize the chances of a successful verification.

The verification flow is initiated with an API call that returns a URL to be hosted in an iframe or mobile web view, where users complete the verification process. The available verification methods are determined by your product configuration in the Compliance Studio, ensuring compliance with jurisdiction requirements.

APIScenario
/age-verification/perform-access-age-verificationTo verify the age of a user before getting access to a feature, mature content, or the product itself.
/age-verification/perform-trusted-adult-verificationTo perform trusted adult (parent or guardian) verification.
/age-verification/perform-age-appealFor users who have failed age verification but want to appeal the decision.

The Age Verification APIs are standardized in terms of the request & response format.

Request body

PropertyDescriptionRequired?
jurisdictionThe jurisdiction in which the age verification should happenYes
criteriaThe criteria for age verificationYes
subject.emailIf the user verified their age with k-ID in any other context with an email address, then the original age is returned instead of asking the user to estimate or prove their age again.No
subject.claimedAgeIf a user was asked for their age in an age gate, used to inform the age estimation processNo
subject.idAn identifier used across multiple verification methods to report multiple failed attempts. This can be a temporary session ID, or hashed user ID.No
options.facialAgeEstimation.minAgeThe minimum acceptable age from facial age estimation results. This should typically be set higher than criteria.age to account for the inherent variance in age estimation technology. For example, if your requirement is 18+, setting minAge to 21-25 provides a confidence buffer that reduces false positives. This ensures users who pass facial age estimation are more likely to meet your actual age requirement.No

Sample:

{
"jurisdiction": "US-CA",
"subject": {
"email": "user@example.com",
"claimedAge": 23,
"id": "3854909b-8888-4bed-9282-24b74c4a3c97"
},
"criteria": {
"ageCategory": "DIGITAL_YOUTH_OR_ADULT"
},
"options": {
"facialAgeEstimation": {
"minAge": 21
}
}
}

Response body

A successful request to the Age Verification API returns the following response.

PropertyDescription
idA unique verification ID generated by Age Verification Service
urlThe age verification URL that must be embedded in an iframe and presented to the user, for them to verify themselves.

Sample:

{
"id": "7854909b-9124-4bed-9282-24b44c4a3c97",
"url": "https://family.k-id.com/verify?token=eyJ..."
}

Embedding the verification interface

Use the returned URL to create an iframe in your website or app. Users complete their verification through this interface, with available methods automatically adapting to jurisdictional requirements.

<div id="verification-container">
<iframe
id="verification-widget"
src="VERIFICATION_URL"
width="100%"
height="600"
frameborder="0"
allow="camera;payment;publickey-credentials-get;publickey-credentials-create">
</iframe>
</div>

The allow attribute is required to enable the following features:

  • camera: Required for facial age estimation
  • payment: Required for credit card verification
  • publickey-credentials-get and publickey-credentials-create: Required for WebAuthn-based verification methods

Verification result

Once the user has successfully completed the age verification, or the user has retried the maximum number of times and hasn't succeeded, the Age Verification Result is delivered through both client-side and server-side channels. Implementations should use a combination of both: client-side events are best for controlling UI elements, while for data integrity, the actual results should come from either a webhook or a call to /age-verification/get-status.

Client-side (DOM events) - If the URL from the response body is included in an iframe, it's sent to the parent frame as a window message (MessageEvent) with a Verification.Result structure.

Server-side (webhooks) - An event is sent to the registered webhook in the form of a Verification.Result event.

Example of accessing the window message:

const handleMessage = (event: MessageEvent) => {
const message = event.data;
if (message.eventType === "Verification.Result") {
// Use DOM Events for immediate UI updates
updateUI(message);
}
};

window.addEventListener("message", handleMessage);
important

For data integrity, always verify results with events from webhooks or by calling /age-verification/get-status rather than relying solely on DOM Events. DOM Events are best suited for responsive UI updates.

The data element of the window event and the webhook event contains the following properties.

PropertyDescription
idThe verification ID for which this is the result.
statusIndicates a PASS or FAIL status, based on whether the user met the age criteria or not.
ageCategoryIndicates the age category the user belongs to in the jurisdiction specified in the request. Supported values are adult, digital-youth or digital-minor
methodIndicates the method used for the verification. Supported values are id-document, age-estimation, age-attestation, credit-card, social-security-number
failureReasonThe reason the verification failed. Supported values are age-criteria-not-met, max-attempts-exceeded, or fraudulent-activity-detected. This is only set if status is FAIL
ageReturns the lower bound and higher bound of the estimated or verified age as low and high.

Sample:

{
"eventType": "Verification.Result",
"data": {
"id": "5a58e98a-e477-484b-b36a-3857ea9daaba",
"status": "PASS",
"ageCategory": "adult",
"method": "id-document",
"age": {
"low": 25,
"high": 25,
}
}
}

Handling a window event:

const handleMessage = (event: MessageEvent) => {
const message = event.data;
if (message.eventType === "Verification.Result" && ) {
if (message.data.status === "PASS") {
window.location.href = `https://www.example.com/success?verificationId=${message.data.id}`
}
if (message.data.status === "FAIL") {
window.location.href = `https://www.example.com/fail?verificationId=${message.data.id}`
}
}
};

window.addEventListener("message", handleMessage);

Verification error

If an unexpected error has occurred, a JavaScript event fires so that your implementation can gracefully handle the error.

For detailed information about the event structure, see Verification.Error.

Sample Message:

{
"eventType": "Verification.Error",
"method": "credit-card",
"status": "ERROR"
}

Checking verification status

In addition to sending events both in JavaScript and through the k-ID webhook, it's also possible to query for status for a verification. This is useful to be able to handle cases where the registered webhook was unreachable for a period of time, and the status event was never sent. To get status for a verification, use the /age-verification/get-status API. The data structure returned is identical to the Verification.Result event data sent to the webhook. For more information about webhook events, see Webhooks.

Limiting verification attempts

Each verification request allows users three attempts per available verification method. A verification fails if:

  • All available verification methods have been exhausted and an age can't be determined
  • An age is determined but falls below the required threshold for your criteria

When a verification fails, you can allow users to initiate a new verification attempt. However, to prevent misuse and abuse of the verification system, you should implement rate limiting on additional verification attempts. For example, you might limit users to three verification attempts within a 24-hour period.

Use the subject.id field in the verification request to track attempts across multiple verification requests. This field should contain a consistent identifier for the user (such as a temporary session ID or hashed user ID), allowing you to:

  • Track the number of verification attempts per user
  • Implement time-based rate limiting (for example, 3 attempts per 24 hours)
  • Prevent users from bypassing limits by creating new sessions
Best practice

Implement rate limiting on your server before initiating verification requests. This prevents unnecessary API calls and helps protect your system from abuse.

Verification methods

For detailed information about all available verification methods, see Verification methods.