API referenceAge check API

Age check API

Estimate whether someone is old enough from a selfie, with a fall back to an ID date of birth when the estimate is too close to the limit.

POST /api/v1/kyc/age-estimation estimates how old the face in a selfie looks and compares it with a minimum age. It is the same check as the Age check option on forms (see Age check), available on its own.

The result is an estimate from a photo, not proof of age. Every response says so (isEstimate, disclaimer). Close to your limit the answer is inconclusive by design: fall back to an ID check.

Authenticate with an API key (Authorization: Bearer ck_live_…) with the scope kyc:write. See Authentication. The photo is processed in memory and is never stored.

Request

Send either multipart/form-data or JSON.

curl -X POST https://app.certivant.com/api/v1/kyc/age-estimation \
  -H "Authorization: Bearer $CERTIVANT_API_KEY" \
  -H "Idempotency-Key: signup-8841" \
  -F image=@selfie.jpg \
  -F minAge=18 \
  -F buffer=5
{
  "imageBase64": "/9j/4AAQSkZJRg…",
  "minAge": 18,
  "buffer": 5,
  "dateOfBirth": "1990-02-03"
}
FieldTypeNotes
image / imageBase64file / stringOne front-facing selfie with a single face. JPEG, PNG, WebP or HEIC, up to 10 MB. A data: URL is accepted
minAgeinteger 1–120, optionalDefaults to your organization setting (Settings → Fraud prevention), initially 18
bufferinteger 0–30, optionalYears either side of minAge inside which the estimate is not trusted. Defaults to your organization setting, initially 5
dateOfBirthYYYY-MM-DD, optionalThe date of birth from an ID you have already verified. Used when the estimate is not conclusive

Send an Idempotency-Key header to make a retry free: the same key is charged once.

Response

{
  "data": {
    "result": "pass",
    "method": "estimate",
    "minAge": 18,
    "buffer": 5,
    "isEstimate": true,
    "estimatedAge": 31.4,
    "estimateSpread": 3.2,
    "estimateConfidence": "high",
    "disclaimer": "An estimate from a photo, not proof of age.",
    "chargedCents": 7
  }
}
FieldNotes
resultpass, fail or inconclusive
methodestimate — the selfie decided; id_document — dateOfBirth decided; none — nothing could decide
isEstimateTrue when the selfie estimate is part of the answer
estimatedAge, estimateSpread, estimateConfidenceThe estimate in years, how uncertain it is, and high or low. Present when an estimate was made
idAgeAge in whole years from dateOfBirth, when it was used
fallbackReasonWhy the ID was needed: near_limit, low_confidence, no_estimate or estimate_mismatch
mismatchA confident estimate and the ID disagree. Treat as a case for manual review
idCheckRequiredTrue when the result is inconclusive and you sent no dateOfBirth: run an ID check and call again with the date of birth, or send the person to a verification
disclaimerAlways present. Show it wherever you display the estimate
chargedCentsWhat this call cost

How the decision is made

  • Estimate at or above minAge + buffer → pass.
  • Estimate below minAge − buffer → fail.
  • In between, or the model is unsure of its estimate → the dateOfBirth decides if you sent one. Without it the result is inconclusive.
  • When you send a dateOfBirth and it clearly contradicts the estimate, mismatch is true: an estimate far above the limit with an under-age date of birth is a fail (the date of birth wins); an estimate far below the limit with an adult date of birth is inconclusive, for a person to look at.

Errors

StatusWhen
400Missing or invalid image, minAge, buffer or dateOfBirth
402Not enough credit to run the check
403Age estimation is not included in your plan
413Image larger than 10 MB
415Not a supported image type
422No usable face was found (and no dateOfBirth to fall back on)
502The estimation service is unavailable. Retry with the same Idempotency-Key

When no face is found but you sent a dateOfBirth, the call still answers from the ID (method: "id_document").

Billing

Age estimation is a plan feature with an included monthly quota and a pay-as-you-go price per check from your credit balance. A call that returns 402 or 403 is not charged. Every check is recorded in your audit log (age_estimation.checked) with the result and method, never the photo or the date of birth.

On a verification

When a form has the age check on, the verification itself carries the result: its review triggers or disqualifiers may contain age_requirement_not_met or age_check_inconclusive, and policies and workflows can test age.checked, age.result, age.method, age.estimatedAge, age.minimum, age.meetsMinimum and age.mismatch.