End-to-end age verification flow recommended by Tuteliq to enforce strict 18+ access on any platform that serves age-restricted content, using Tuteliq (identity + liveness verification).
1. Overview
Any platform that hosts age-restricted content, adult material, gambling, alcohol, tobacco, certain AI companion products, or regulated financial services, is legally required to verify that every visitor meets the applicable age threshold before they can interact with the platform. Verification is performed by Tuteliq, a third-party identity/liveness provider.
The flow is:
- The user lands on any page of the application.
- A blocking modal (AgeVerification) overlays the entire app until the user is verified.
- The user creates a Tuteliq verification session, completes it on Tuteliq's hosted page (ID document scan + selfie liveness), and returns.
- The browser polls the application's backend, which polls Tuteliq, until a terminal status is reached.
- On success, a flag is persisted in localStorage so the user is not re-prompted on subsequent visits.
2. Why This Matters. Risks of Non-Compliance
Age verification has moved from an optional safeguard to a legal obligation in a growing number of jurisdictions, and enforcement has intensified sharply since 2024. Platforms that cannot demonstrate compliance face four categories of risk.
2.1 Financial Penalties
Regulators now have both the authority and the appetite to impose very large fines. Representative statutory maximums:
Regulation
Jurisdiction
Maximum penalty
COPPA
United States
Up to USD 53,088 per violation (each affected child can count as a separate violation).
Online Safety Act
United Kingdom
Up to GBP 18 million or 10% of global annual turnover, whichever is higher.
Digital Services Act (DSA)
European Union
Up to 6% of global annual revenue.
GDPR / GDPR-K
Up to EUR 20 million or 4% of global annual turnover.
Online Safety Amendment
Australia
Up to AUD 50 million.
Social media / child protection law
Brazil
Up to BRL 50 million.
Actual recent settlements show these figures are not theoretical:
- Epic Games (Fortnite), 2022, USD 275 million COPPA penalty, USD 520 million total settlement, the largest civil penalty ever imposed for violating an FTC rule.
- Google / YouTube, 2019, USD 170 million settlement with the FTC and New York Attorney General for collecting children's data without parental consent.
- TikTok, 2019, USD 5.7 million (with a new DOJ/FTC action for alleged ongoing violations proceeding through 2025–2026).
- Disney, 2025, USD 10 million settlement over mislabelled child-directed videos.
- HoYoverse (Genshin Impact), 2025, USD 20 million proposed settlement, plus a ban on selling loot boxes to under-16s without parental consent.
2.2 Criminal Liability
In several jurisdictions, deliberate or reckless violations can create personal criminal liability for company officers and directors, not just the corporate entity:
- UK Online Safety Act. Senior managers of in-scope services can be prosecuted for failing to comply with a confirmation decision from Ofcom relating to children's safety duties, or for failing to respond to information requests.
- US state laws. Several state statutes create personal officer liability for serious or repeated violations.
- EU DSA. National authorities may impose sanctions on individuals responsible for compliance failures at Very Large Online Platforms (VLOPs).
2.3 Civil Litigation and State Attorney General Actions
Beyond regulator-led fines, companies face private class actions and coordinated state AG litigation:
- In March 2026, a New Mexico jury found Meta liable for violating state consumer protection law over child safety failures and ordered USD 375 million in civil penalties, the first jury verdict in a wave of state-led actions.
- A coalition of 42 US attorneys general has filed actions against Meta over alleged harm to young users.
- Snapchat and TikTok reached settlements in the same New Mexico matter earlier in 2026; further trials involving Meta, YouTube, and other platforms are scheduled.
State AGs can act independently of the FTC under COPPA, meaning a single compliance failure can generate simultaneous actions across federal and multiple state jurisdictions.
2.4 Reputational Damage
Reputational harm is harder to quantify but consistently follows enforcement. Press coverage fixates on the most damaging framing, typically "company X knowingly exposed children to [tracking / advertising / harmful content]", and that association is very difficult to reverse. Consumer trust in how companies handle children's data is now a measurable factor in purchasing decisions and brand loyalty, particularly among parents.
2.5 Who Counts as a Minor
The threshold varies by jurisdiction, which is why the age gate must be configurable per market:
Threshold
COPPA (US, current)
Under 13
COPPA 2.0 (US, Senate-passed March 2026)
Under 17
CPRA (California)
Opt-in for sale/share under 16
CAADC (California)
Under 18
GDPR / GDPR-K (EU)
13–16 (varies by Member State)
UK Online Safety Act
Australia Online Safety Amendment
Under 16 (social media)
India DPDP Act
For platforms with international audiences, designing for the most protective standard that applies to any of the markets served is usually the pragmatic choice.
2.6 What Regulators Now Expect
Self-declaration of age (a simple "I am over 18" checkbox) does not meet the standard of "highly effective" age assurance required by, for example, the UK Online Safety Act. An effective, defensible age verification process must:
- Operate before any data collection begins, no tracking scripts or third-party tags may load before age status is confirmed.
- Be configurable by jurisdiction, thresholds and obligations differ, and the system must adapt.
- Be auditable, every verification event must be logged and retrievable on request.
- Automatically apply downstream protections, once a minor is detected, data collection, sale, and sharing must all be blocked and applicable rights (e.g. CPRA "Do Not Sell or Share") applied.
- Be integrated with consent management, not bolted on, so that age status and consent share a single source of truth.
The architecture described in the rest of this document is designed to meet these expectations.
Source and further reading: Usercentrics, Age Verification Compliance: Regulations, Risks, and What Businesses Must Do Now.
3. Storage. How a Verified User Is Remembered
Verification state lives only in the browser (localStorage). Tuteliq verification data is not stored server-side by the application.
Key
Value
Purpose
app_age_verified
"true"
Master flag, when present and "true", the user bypasses the gate.
app_age_session_id
Tuteliq session_id (string)
Last successful Tuteliq session ID, kept for audit/debug.
app_cookie_consent
"all" | "essential" | "declined"
Cookie banner answer (shown after age verification).
The app_ prefix is a placeholder, replace it with your own namespace (e.g. yourbrand_age_verified) so the keys don't collide with other scripts on the same origin.
Implications
- Per-browser, per-device. Clearing site data, switching browsers, or using incognito requires re-verification.
- No expiration in code by default. Once app_age_verified === "true" is set, the user is treated as verified indefinitely on that browser. (Tuteliq sessions themselves expire ~10 minutes after creation; the stored result is what is trusted, not a live session.) Some jurisdictions may require periodic re-verification, if so, store a timestamp alongside the flag and expire it accordingly.
- Not tied to an authenticated user. The flag is set before sign-in and survives sign-out. Sign-in does not re-trigger verification.
Pages exempted from the gate
- /access-denied, shown when a user declines the gate or fails verification. Rendered without the gate so the user is not trapped in a loop.
4. Architecture
Frontend
File
Role
src/components/compliance/ComplianceGate.tsx
Top-level wrapper. Reads localStorage, shows the modal when not verified, and persists the flag on success.
src/components/compliance/AgeVerification.tsx
The modal UI + state machine. Creates the Tuteliq session, opens the hosted page, and polls for the result.
src/components/compliance/CookieConsent.tsx
Shown immediately after verification (one-time).
src/pages/AccessDenied.tsx
Branded "you cannot enter" page.
Backend (example: Supabase Edge Functions)
The example below uses Supabase Edge Functions, but any server runtime that can hold a secret API key and make outbound HTTPS calls works equally well (Cloudflare Workers, AWS Lambda, a Node/Express service, etc.).
Function
create-age-verification
Calls tuteliq.createVerificationSession({ mode: AGE }) and returns { session_id, url, expires_at } to the client.
check-age-verification
Calls tuteliq.getVerificationSession(session_id) and normalizes the response into { status, verified, is_minor, age, liveness_valid, raw_status }.
Both functions read the TUTELIQ_API_KEY secret from the project's secret store. They use the official npm:@tuteliq/sdk@^2.3.0 package.
5. Verification State Machine (client)
AgeVerification runs through these states:
State
What's happening
idle
Modal shown with Verify My Age / I am under 18. Exit buttons.
creating
A blank tab is opened synchronously (Safari requirement), then create-age-verification is invoked.
ready
Session created. The Tuteliq URL is shown as a fallback link if the auto-redirect of the pre-opened tab failed.
polling
The Tuteliq page is open in another tab. Poll check-age-verification every 3 seconds, up to 60 attempts (3 minutes). A manual Next button is also shown.
verified
onVerified(sessionId) fires → ComplianceGate writes app_age_verified = "true".
failed
Terminal error or timeout. The user can Try Again or Exit.
Polling triggers
Polling runs on multiple signals to be resilient to mobile browser throttling:
- setInterval every 3 seconds while in polling / ready.
- window focus event (when the user returns to your tab).
- document visibilitychange event (mobile-friendly).
- The ?age_verified=true query param. Tuteliq redirects back with this flag, which re-triggers an immediate check.
- The manual Next button in the modal.
Status normalization
The Tuteliq API returns varied status strings; normalize them in check-age-verification:
- Completed-equivalent: completed, complete, verified, approved → completed
- Failed-equivalent: failed, declined, rejected, expired, cancelled → failed
- Pending: pending, processing, created, in_progress, submitted, sent, initiated, started, awaiting_result, requires_input → keep polling
- Unknown: keep polling, but accept if verified === true or is_minor === false is present.
A user is considered verified when:
6. End-to-End Flow
7. Tuteliq Response Shape (reference)
A successful Tuteliq result returned from getVerificationSession:
A failure case where the document could not be read:
In this case is_minor === null so the user is not marked verified, they must retry.
8. Failure Modes & UX
Failure
UI behaviour
Session creation fails (network, missing API key, Tuteliq subscription issue)
"Verification service is temporarily unavailable. Please try again later."
Session expires before completion
"Verification session expired. Please try again."
Liveness check fails
"Liveness check failed. Please try again in good lighting, look directly at the camera, and blink naturally."
Document unreadable / is_minor null
Generic "Verification was not completed. Please try again."
User declines / under 18
Redirect to /access-denied.
Polling timeout (>3 min)
"Verification session timed out. Please try again."
9. Jurisdiction-Specific Add-Ons
Depending on the markets served, additional checks may be layered on top of the base Tuteliq age flow:
- Brazil, CPF (taxpayer ID) verification may be required in addition to age verification.
- United States. For platforms collecting data from users under 13 (or under 17 once COPPA 2.0 is in force), verifiable parental consent is required, not just age confirmation.
- European Union. For users between the Member State's digital-consent age and 18, parental consent flows may be required under GDPR-K, and DSA obligations around profiling and advertising to minors apply.
- United Kingdom. The Online Safety Act requires "highly effective" age assurance for pornography and other specified harmful content; self-declaration is explicitly insufficient.
Document each add-on separately and wire it into the same ComplianceGate so that age status and jurisdiction-specific requirements share a single source of truth.
10. Configuration Reference
- localStorage keys, app_age_verified, app_age_session_id, app_cookie_consent (replace app_ with your own namespace; typically defined as constants in ComplianceGate.tsx).
- Backend secret, TUTELIQ_API_KEY stored in your backend's secret manager. Never exposed to the client.
- Redirect target, configure Tuteliq's post-verification redirect URL to include ?age_verified=true so the client can pick up the signal immediately.
Keep TUTELIQ_API_KEY server-side only. Never embed it in your frontend bundle or expose it through public endpoints.