Estimate a user's age from a selfie — no ID upload, no friction. Under two seconds, ±3.5-year accuracy, iBeta-certified liveness on the same capture. $0.10 per check, 500 free/month.
Estimate age in milliseconds. No document required.
On-device face analysis returns an age estimate in under two seconds — no ID
photo, minimum personal data. Built on the same engine certified by iBeta
Level 1 for presentation-attack detection.
How it works
From sign-up to verified user in four steps.
Step 01
Create the workflow
Pick the checks you want — ID, liveness, face match, sanctions, address, age, phone, email, custom questions. Drag them into a flow in the dashboard, or post the same flow to our API. Branch on conditions, run A/B tests, no code required.
Step 02
Integrate
Embed natively with our Web, iOS, Android, React Native, or Flutter SDK. Redirect to a hosted page. Or just send your user a link — by email, SMS, WhatsApp, anywhere. Pick what fits your stack.
Step 03
User goes through the flow
Didit hosts the camera, the lighting cues, the mobile hand-off, and accessibility. While the user is in the flow, we score 200+ fraud signals in real time and verify every field against authoritative data sources. Result in under two seconds.
Step 04
You receive the results
Real-time signed webhooks keep your database in sync the moment a user is approved, declined, or sent to review. Poll the API on demand. Or open the console to inspect every session, every signal, and manage cases your way.
Built for developers · Built against fraud · Open by design
Six capabilities. One feature flag. AGE_ESTIMATION.
Every capability below is a toggle on the same module. No upsell tiers, no separate SKUs, no add-on calls. Switch them on per workflow or pass them inline on the API call.
A minimum-data answer for age-restricted commerce — adult content, alcohol delivery, online gambling. A single passive selfie covers the clear-pass and clear-fail majority, cutting drop-off vs a full ID upload by an order of magnitude. Aligns with UK Online Safety Act and California's age-appropriate code.
Age check
Single passive frame · No ID upload
Selfie only
1 frame · passive
age_estimation
24 yrs
band 18 – 29
verdict
Clear pass
threshold 18+
document
None required
no ID upload
cost
$0.10
per selfie
Ready · UK Online Safety Act · CCPA Age-Appropriate
02 · Accuracy
±3.5 years across every age range.
Average error 3.5 years overall — 89% of estimates land inside ±5 years, 76% inside ±3 years. Per-bracket performance is published — 1.5 years under 18, 2.8 years for 18–25, 3.9 years for 41–60 — so you can size your threshold against real numbers, not vendor adjectives.
Accuracy
Mean absolute error · Per-bracket
±3.5y MAE
±3.5y
Overall MAE
89%
Inside ±5y
76%
Inside ±3y
BracketDistributionMAE
<18
1.5y
18 – 25
2.8y
26 – 40
3.4y
41 – 60
3.9y
03 · Demographic fairness
Trained on millions of faces. Across every demographic.
Bias is the biggest failure mode of age-estimation models, and the one regulators look for. Our models train on a balanced corpus across age, ethnicity, gender, and lighting condition, with per-bracket error published rather than averaged away. Retrained continuously to stay in front of demographic drift.
Demographic fairness
Per-axis MAE · Continuous retraining
Balanced
Age±3.5y
Ethnicity±3.7y
Gender±3.4y
Lighting±3.6y
Training set
12.4M faces
Retraining
Quarterly
Last update
Apr 2026
04 · Configurable thresholds
Tune the policy per workflow and per country.
Decline threshold (default 18) and face-liveness floor per workflow. Layer per-country rules on top — min/max age per country with state-level overrides where it matters (Mississippi 21, Alabama 19, US default 18). One click applies the worldwide legal age of majority as a baseline; tune the exceptions.
Threshold policy
Per workflow · Per country
3 bands
Estimate bandAction
Estimate < 15
Decline
Estimate 15 – 25
Review
Estimate > 25
Approve
Per-country overrides · Minimum age
🇺🇸US default18+
🇺🇸Mississippi21+
🇺🇸Alabama19+
🇬🇧UK18+
05 · Adaptive ID fallback
Borderline cases auto-route to a document check.
Clear passes and clear fails finish on the selfie alone. Borderline estimates — the uncertain minority near your threshold — auto-trigger our Adaptive Age Verification flow, governed by the per-country rules on the ID step. Most users complete with a selfie; the document check fires only when the math says you need it. Billed at $0.15 per ID Verification fallback.
Adaptive routing
Selfie · Borderline · ID fallback
Live
1,284
Clear pass
47
Borderline
9
Clear fail
Fallback fired · usr_9f01a3c routed to ID verification$0.15
Ausr_a8c4f0232 yrs · band 26 – 40Clear pass
Musr_9f01a3c17 yrs · band 15 – 19ID required
Lusr_4d2b6e113 yrs · band 11 – 15Clear fail
06 · Liveness foundation
One capture. Two signals. Same engine as Liveness.
Age Estimation runs on top of our iBeta Level 1 PAD (presentation attack detection) liveness pipeline — the same selfie returns a real-human verdict and an age band. Defeats deepfakes, printed photos, screen replays, and silicone masks before the age model ever runs. Toggle it on a Liveness workflow and one capture lights up both fields.
One capture · Two signals
iBeta L1 PAD · ISO/IEC 30107-3
Liveness + Age
Approved · 98age 24 · band 18 – 29
Printed photoBlocked
Screen replayBlocked
Silicone maskBlocked
AI deepfakeBlocked
Same engine · iBeta L1 PAD certified · re-tested annually
Integrate
Two endpoints. Same JSON. Same price.
Create a session when you want our hosted UI to handle the selfie (and the Adaptive ID fallback for borderline cases). Call the standalone endpoint when you already have the selfie. Same age block either way.
You own the capture. We return the age inline.docs →
Agent-ready integration
Ship Age Estimation in one prompt.
Paste the block below into Claude Code, Cursor, Codex, Devin, Aider, or Replit Agent. Fill in the my_stack placeholder with your framework, language, and use case. The agent provisions Didit, creates the workflow, wires the webhook, and ships.
didit-integration-prompt.md
# Didit Age Estimation — integrate in 5 minutes
You are integrating Didit's Age Estimation module into <my_stack>. Follow
these steps exactly. Every URL, header, and enum value below is canonical
— do not paraphrase or "improve" them.
## 1. Provision an account
- Sign up: https://business.didit.me (no credit card required).
- Or provision programmatically: POST https://apx.didit.me/auth/v2/programmatic/register/
(returns an API key bound to the workspace + application).
## 2. Two integration paths — pick one
### Path A — Workflow Builder (hosted UI)
Best when you want Didit to handle the camera, framing, low-light
fallback, mobile handoff, and accessibility for you. Required if you want
Adaptive Age Verification (auto-fall-back to ID for borderline cases).
1. Create a workflow that contains the AGE_ESTIMATION feature:
POST https://verification.didit.me/v3/workflows/
Authorization header: x-api-key: <your-api-key>
Body: workflow_label, features array with the single entry
{ feature: "AGE_ESTIMATION" } (UPPERCASE — strict enum)
Optional config:
- age_estimation_decline_threshold (default 18)
- face_liveness_score_decline_threshold (default 30)
- adaptive_id_verification (when true, borderline cases trigger ID
verification fallback governed by per-country age restrictions on
the ID Verification step)
- per_country_age_restrictions (map of country -> min / max age,
with optional state-level overrides)
2. Create a verification session for an end user:
POST https://verification.didit.me/v3/session/
Body: workflow_id (from step 1), vendor_data (your own user id).
Response: session_url — redirect the user to it.
3. Listen for webhook callbacks (see "Webhooks" below).
### Path B — Standalone server-to-server API
Best when you already have a selfie image (mobile SDK capture, native
onboarding app, reseller pipeline) and only need a numeric age estimate
plus passive-liveness verdict on it. No adaptive ID fallback on this
path — wire that yourself if you need it.
POST https://verification.didit.me/v3/age-estimation/
Content-Type: multipart/form-data
Body fields:
- user_image (required, file — single selfie)
- age_estimation_decline_threshold (optional integer 0-100, default 18)
- face_liveness_score_decline_threshold (optional integer 0-100, default 30)
- rotate_image (optional boolean, default false)
- save_api_request (optional boolean, default true)
- vendor_data (optional string, your user id)
Response: JSON with request_id, age_estimation block, created_at.
## 3. Webhooks (Path A only — Path B returns synchronously)
- Register a webhook destination once via
POST https://verification.didit.me/v3/webhook/destinations/
Body: url, subscribed_events: ["session.verified", "session.review_started",
"session.declined"]
- Response includes secret_shared_key — store it.
- Every webhook delivery carries an X-Signature-V2 header you MUST verify
before trusting the payload. HMAC-SHA256 verification MUST run against the raw body bytes (the raw payload as Didit sent it) BEFORE any JSON parsing — re-serialising the parsed body changes whitespace and key order, which invalidates the signature.Algorithm:
1. sortKeys(payload) recursively
2. shortenFloats (truncate trailing zeros after the decimal point)
3. JSON.stringify the result
4. HMAC-SHA256 with the secret_shared_key
5. Hex-encode, compare to the X-Signature-V2 header.
## 4. Reading the report
### Path A (session) — age_estimation lives on the liveness object
The liveness object on the session report includes age_estimation as a
number-of-years field on the same selfie capture:
- liveness.status "Approved" | "Declined" | "In Review" | "Not Finished"
- liveness.method "PASSIVE" | "FLASHING" | "ACTIVE_3D"
- liveness.score number 0-100 (normalized liveness score)
- liveness.reference_image signed URL to the captured selfie (60-minute TTL)
- liveness.age_estimation estimated age in years (e.g. 24.3)
- liveness.warnings Array of risk objects (see below)
### Path B (standalone) — top-level age_estimation block
- request_id uuid
- age_estimation.status "Approved" | "Declined" | "In Review"
- age_estimation.method "PASSIVE"
- age_estimation.score number 0-100 (passive-liveness score)
- age_estimation.age_estimation estimated age in years (e.g. 27.33)
- age_estimation.user_image.entities array of detected faces, each with
age, bbox, confidence, gender
- age_estimation.user_image.best_angle integer
- age_estimation.face_quality 0-100 face image quality score
- age_estimation.face_luminance 0-100 face luminance score
- age_estimation.warnings Array of risk objects (see below)
- created_at ISO8601
### Warning catalog (both paths)
- AGE_BELOW_MINIMUM estimated age below the configured threshold
- AGE_NOT_DETECTED unable to estimate age (quality / lighting)
- LOW_LIVENESS_SCORE passive-liveness score below threshold
- NO_FACE_DETECTED no face in the capture
- LIVENESS_FACE_ATTACK presentation attack suspected
- FACE_IN_BLOCKLIST face matches an entry in your blocklist
- POSSIBLE_DUPLICATED_FACE face matches a previously verified face
## 5. Hard rules — do not change
- Base URL for /v3/* endpoints is verification.didit.me (NOT apx.didit.me).
- Feature enum is UPPERCASE: AGE_ESTIMATION, LIVENESS, ID_VERIFICATION,
FACE_MATCH, AML, IP_ANALYSIS.
- Method enum is UPPERCASE: PASSIVE, FLASHING, ACTIVE_3D.
- Auth header is x-api-key (lowercase, hyphenated).
- Webhook signature header is X-Signature-V2 (NOT X-Signature).
- Always verify webhook signatures before trusting payload data.
- Status casing matches exactly: "Approved", "Declined", "In Review",
"Not Finished" (title-cased, space-separated).
- Reference image / video URLs are signed and expire in 60 minutes —
store only the verdict + score, never the biometric media.
## 6. Pricing reference (public)
- AGE_ESTIMATION standalone or bundled inside a workflow: $0.10 per check
- Adaptive fallback to ID Verification (when triggered): $0.15 per check
- Bundled in a full KYC workflow alongside Liveness + ID + IP: $0.33 per session
- 500 free verifications every month, forever, on every account.
## 7. Verify your integration
- Sandbox starts on signup at https://business.didit.me — no separate flag.
- Test images: deterministic synthetic faces returned in sandbox
(predictable estimated age band; trigger AGE_BELOW_MINIMUM by sending
the canonical "minor" test image).
- Switch to live: flip the application environment toggle in console.
When in doubt: https://docs.didit.me/core-technology/age-estimation/overview
Open a new country in one click. We do the hard work.
We open the local subsidiaries, secure the licenses, run the penetration tests, earn the certifications, and align with every new regulation. To ship verifications in a new country, flip a toggle. 220+ countries live, audited and pen-tested every quarter — the only identity provider an EU member-state government has formally called safer than in-person verification.
500 free verifications every month, forever. Pay-as-you-go for production. Custom contracts, data residency, and SLAs (Service Level Agreements) on Enterprise.
Free
Free
$0 / month. No credit card required.
Free KYC bundle (ID Verification + Passive Liveness + Face Match + Device & IP Analysis) — 500 / month, every month
Blocklisted Users
Duplicate Detection
200+ fraud signals on every session
Reusable KYC across the Didit network
Case Management Platform
Workflow Builder
Public docs, sandbox, SDKs, MCP (Model Context Protocol) server