Skip to main content

Verification.Result

Emitted with the result of a verification attempt.

Fields

FieldTypeRequiredDescription
eventTypestringyesAlways "Verification.Result"
dataobjectyesVerification result data
data.idstring (UUID)yesThe unique verification ID
data.statusstringyesCan be PASS or FAIL
data.ageCategorystringnoThe estimated age category. Can be adult, digital-youth, or digital-minor. Only present when status is PASS and age is present
data.methodstringnoThe verification method used. Always present for PASS status. For FAIL status, only present if failureReason is age-criteria-not-met
data.failureReasonstringnoThe reason the verification failed. Always present when status is FAIL. Can be age-criteria-not-met, max-attempts-exceeded, or fraudulent-activity-detected
data.ageobjectnoThe age details. Present when both age.low and age.high are available. For FAIL status, only present if failureReason is age-criteria-not-met
data.age.lownumbernoThe lower bound of the estimated age. In the case of a hard age verification method, such as an ID document check, this is the exact age
data.age.highnumbernoThe upper bound of the estimated age. In the case of a hard age verification method, such as an ID document check, this is the exact age
data.dobstring (YYYY-MM-DD)noVerified date of birth. Only included when the verification method provides it. Always included if available from the method

Example

{
"eventType": "Verification.Result",
"data": {
"id": "4e57301e-a4d1-498f-ac3f-f3d4de19abf6",
"status": "PASS",
"method": "id-document",
"age": {
"low": 43,
"high": 43
},
"dob": "1981-06-20"
}
}

Verification event contract

Overview

This section defines the API contract for verification status delivered to you through two mechanisms:

  1. Webhook Events: Verification.Result webhook events sent when a verification completes
  2. API Endpoint: GET /age-verification/get-status endpoint for polling verification status

This contract specifies field presence rules, data types, and interpretation guidance for all possible outcome types. While both mechanisms provide similar data, there are important differences in status values, field presence, and structure that you must be aware of.

DOM Messages Aren't Authoritative

Verification results are also communicated to front-end applications via DOM messages for UI control purposes. However, only webhook events and the GET /age-verification/get-status endpoint responses should be considered reliable, authoritative data sources for integration logic. DOM messages are provided solely for front-end application state management and shouldn't be used as the basis for critical business decisions or data persistence.

Data structures

Webhook event structure

Webhook events are wrapped in an event envelope:

{
"eventType": "Verification.Result",
"data": {
"id": "uuid",
"status": "PASS" | "FAIL",
"ageCategory": "adult" | "digital-youth" | "digital-minor" | null,
"method": "id-document" | "credit-card" | "self-confirmation" | "social-security-number" | "email-confirmation" | "age-estimation-scan" | null,
"age": {
"low": number,
"high": number
} | null,
"dob": "YYYY-MM-DD" | null,
"failureReason": string | null
}
}

API endpoint response structure

The GET /age-verification/get-status endpoint returns a direct response:

{
"id": "uuid",
"status": "PASS" | "FAIL" | "PENDING" | "IN_PROGRESS",
"ageCategory": "adult" | "digital-youth" | "digital-minor" | null,
"method": "id-document" | "credit-card" | "self-confirmation" | "social-security-number" | "email-confirmation" | "age-estimation-scan" | null,
"age": {
"low": number,
"high": number
} | null,
"dob": "YYYY-MM-DD" | null,
"failureReason": string | null
}

Query Parameters:

  • id (required): The verification ID
  • includeDob (optional, default: false): If true, includes the dob field when available

For complete endpoint documentation, see GET /age-verification/get-status.

Key differences between webhook and API endpoint

AspectWebhook EventAPI Endpoint
Status ValuesOnly PASS or FAILPASS, FAIL, PENDING, IN_PROGRESS
StructureWrapped in { eventType, data }Direct response object
DOB FieldAlways included if availableOnly included if includeDob=true query parameter is set
AgeCategoryOnly present when status is PASSPresent for both PASS and FAIL statuses
MethodOnly present when status is PASSPresent for both PASS and FAIL statuses
When AvailableOnly when verification completesCan be polled at any time, including during verification

Status types

PASS

The verification successfully determined that the user meets the age criteria.

Availability:

  • Webhook: ✅ Sent when verification completes successfully
  • API Endpoint: ✅ Returned when verification is complete and successful

FAIL

The verification determined that the user doesn't meet the age criteria, or the verification process failed because a conclusive age determination couldn't be made, or deceptive behavior was detected. These scenarios result in a FAIL status with the appropriate failureReason values.

Availability:

  • Webhook: ✅ Sent when verification completes with failure
  • API Endpoint: ✅ Returned when verification is complete and failed

Status: PENDING

The verification request has been created but hasn't yet started processing.

Availability:

  • Webhook: ❌ Never sent (webhooks only fire on completion)
  • API Endpoint: ✅ Returned when verification is in initial state

API Endpoint Response for PENDING:

  • id (UUID) - always included
  • status ("PENDING") - always included
  • All other fields are absent

Status: IN_PROGRESS

The verification is currently being processed.

Availability:

  • Webhook: ❌ Never sent (webhooks only fire on completion)
  • API Endpoint: ✅ Returned when verification is actively being processed

API Endpoint Response for IN_PROGRESS:

  • id (UUID) - always included
  • status ("IN_PROGRESS") - always included
  • All other fields are absent

Field presence rules by status

Webhook events

Webhook events are only sent when a verification completes (status is PASS or FAIL). They don't include intermediate statuses such as PENDING or IN_PROGRESS.

Status: PASS

Webhook events

Always included:

  • id (UUID)
  • status ("PASS")
  • method (string) - The verification method used

Sometimes included:

  • ageCategory (string) - One of: adult, digital-youth, digital-minor (only present when age is present)
  • age (object) - Contains both low and high bounds (only present when the verification method provides age information)
  • dob (string, YYYY-MM-DD format) - Verified date of birth, only when the verification method provides it (see Date of birth field section for specific methods). Always included if available.

Never included:

  • failureReason

API endpoint

Always included:

  • id (UUID)
  • status ("PASS")
  • method (string) - The verification method used (if available)

Sometimes included:

  • ageCategory (string) - One of: adult, digital-youth, digital-minor (when age is present)
  • age (object) - Contains both low and high bounds (when the verification method provides age information)

Sometimes included:

  • dob (string, YYYY-MM-DD format) - Only included if includeDob=true query parameter is set AND the verification method provides it (see Date of birth field section for specific methods)

Never included:

  • failureReason
What you need to know
  • Treat PASS status as a successful verification
  • Use the ageCategory field to determine user permissions and access levels when it's present
  • Don't rely solely on age.low or age.high for access control when ageCategory is present, use ageCategory instead
  • You can use dob if it's provided, but don't assume it's always available
  • For the API endpoint: Set includeDob=true in your query parameters if you need DOB data (see GET /age-verification/get-status)

Status: FAIL

Webhook events

Always included:

  • id (UUID)
  • status ("FAIL")
  • failureReason (string) - Reason for the failure

Sometimes included:

  • method (string) - Only present if failure isn't due to max-attempts-exceeded or fraudulent-activity-detected
  • age (object) - Only present if failureReason is age-criteria-not-met
  • dob (string) - Only present when the verification method provides it (see Date of birth field section for specific methods). Always included if available.

Never included:

  • ageCategory - Webhook events only include ageCategory when status is PASS

API endpoint

Always included:

  • id (UUID)
  • status ("FAIL")
  • failureReason (string) - Reason for the failure

Sometimes included:

  • method (string) - Only present if failure is due to age-criteria-not-met
  • age (object) - Only present if failureReason is age-criteria-not-met
  • ageCategory (string) - Only present if age is present
  • dob (string) - Only included if includeDob=true query parameter is set AND the verification method provides it (see Date of birth field section for specific methods)

Never included:

  • ageCategory when age isn't present
What you need to know
  • Treat FAIL status as an unsuccessful verification, don't grant access or permissions
  • Always check failureReason to understand why the verification failed
  • Don't assume age fields are present for FAIL status, they might not be available
  • If age is present in a FAIL result, you can use it for logging or analytics, but don't use it for access control decisions
  • Handle cases where method and age are absent, this indicates a system-level failure, not an age determination failure
  • For webhook events: ageCategory won't be present for FAIL status, so don't try to use it
  • For API endpoint: Even if ageCategory is present for FAIL status, don't use it for access control decisions

Common Failure Reasons:

  • age-criteria-not-met - User's verified age doesn't meet the required threshold
  • max-attempts-exceeded - User has exhausted all available verification attempts (this is the final failure reason when users exhaust retries after failed or inconclusive age determinations)
  • fraudulent-activity-detected - System detected suspicious or fraudulent behavior

Age field population rules

When age object is present

The age object contains two fields:

  • low (number): The lower bound of the age estimate, or the exact age for hard verification methods (for example, ID document)
  • high (number): The upper bound of the age estimate, or the exact age for hard verification methods, or 150 if only the minimum age is known

Conditions for age to be present:

  • The verification method provided age information
  • For FAIL status: failureReason is age-criteria-not-met
What you need to know
  • Always check that both age.low and age.high exist before accessing the age object
  • Don't assume that age.low === age.high means you have an exact age, it might, but it depends on the verification method
  • Don't use age fields for access control when status isn't PASS
  • For PASS status, prefer using ageCategory over raw age values when making access decisions

When ageCategory is present

The ageCategory field is derived from the age and jurisdiction information.

Values:

  • adult - User is classified as an adult
  • digital-youth - User is classified as a digital youth (age-restricted but not a minor)
  • digital-minor - User is classified as a digital minor

Conditions for ageCategory to be present:

  • age object is present
  • Age category was successfully calculated from the age and jurisdiction
  • For FAIL status: failureReason is age-criteria-not-met
What you need to know
  • Use ageCategory for access control decisions when it's present and status is PASS
  • Don't assume ageCategory is always present, even when age is present
  • Handle cases where age is present but ageCategory is absent
  • For FAIL status, don't use ageCategory for access control decisions, even if it's present

When age and ageCategory are absent

Conditions:

  • The verification failed with failureReason of max-attempts-exceeded - No age determination was made
  • The verification failed with failureReason of fraudulent-activity-detected - Age data is excluded for security reasons
  • The verification method didn't provide age information
What you need to know
  • Don't assume age information is always available, handle missing age fields gracefully
  • Don't try to infer age from other fields when age is absent
  • For FAIL status without age fields, rely on failureReason to understand what went wrong

Date of birth field

Format: YYYY-MM-DD (ISO 8601 date format)

When present: The dob field is only included when the verification method provides a verified date of birth. It's not included for methods that only provide age estimates or age ranges. Given the various combinations of verification methods and jurisdictions, you shouldn't perform validation or have expectations about when dob must be present. The field is provided when it's available from the verification method, but its presence can't be guaranteed across all scenarios.

Methods that can provide dob:

  • id-document - When the ID document contains readable date of birth information
  • credit-card - When the credit card verification provides date of birth (not all credit card verifications include DOB)
  • social-security-number - When the SSN verification provides date of birth
  • privy - Always provided (Indonesian identity verification)
  • korean-real-name - Always provided (Korean real-name verification via Inicis)
  • age-attestation - When the attestation includes birth date information
  • singpass - Always provided (Singapore national identity verification)

Methods that NEVER provide dob:

  • age-estimation-scan - Only provides age ranges, not verified DOB
  • email-confirmation - Only provides age estimates, not verified DOB
  • email-estimation - Only provides age estimates, not verified DOB
  • self-confirmation - No verified DOB available

Status conditions:

  • Present for PASS status when the method provides it
  • Present for FAIL status when the method provided it before determining the user didn't meet age criteria
What you need to know
  • Don't assume dob is always present, even for PASS status
  • If dob is present, validate that it's in YYYY-MM-DD format
  • You can use dob for additional validation or logging, but don't rely on it as your primary way to determine age

Method field

When present:

  • Always present for PASS status
  • Present for FAIL status when failureReason is age-criteria-not-met

Possible values:

  • id-document - Government-issued ID document verification (can include DOB)
  • credit-card - Credit card verification (can include DOB)
  • self-confirmation - Self-declared age confirmation (no DOB)
  • age-estimation-scan - Age estimation via document scan (no DOB, only age ranges)
  • social-security-number - SSN-based verification (can include DOB)
  • email-confirmation - Email-based age verification (no DOB, only age estimates)
  • email-estimation - Email-based age estimation (no DOB, only age estimates)
  • privy - Indonesian identity verification (always includes DOB)
  • korean-real-name - Korean real-name verification via Inicis (always includes DOB)
  • age-attestation - Age attestation via k-ID (can include DOB)
  • singpass - Singapore national identity verification (always includes DOB)
  • connect-id - Australian ConnectID verification
What you need to know
  • You can use method for analytics or logging purposes
  • Don't use method for access control decisions

Failure reason values

Common failureReason values:

  • age-criteria-not-met - User's verified age doesn't meet the required threshold
  • max-attempts-exceeded - User has exhausted all available verification attempts
  • fraudulent-activity-detected - System detected suspicious or fraudulent behavior
What you need to know
  • Handle unknown failureReason values gracefully, don't break if you see something unexpected
  • Don't make access decisions based solely on failureReason, always consider the status field
  • It's a good idea to log failureReason for debugging and analytics purposes

Complete field matrix

Webhook events

FieldPASSFAIL
idalwaysalways
statusalwaysalways
methodalwayssometimes¹
ageCategorysometimes²never
agesometimes²sometimes³
dobsometimes⁴sometimes⁴
failureReasonneveralways

¹ Present unless failureReason is max-attempts-exceeded or fraudulent-activity-detected
² Present only if both age.low and age.high are available
³ Present only if both age.low and age.high are available AND failureReason isn't max-attempts-exceeded or fraudulent-activity-detected
⁴ Always included if available from the verification method

API endpoint

FieldPENDINGIN_PROGRESSPASSFAIL
idalwaysalwaysalwaysalways
statusalwaysalwaysalwaysalways
methodneverneversometimes²sometimes¹
ageCategoryneverneversometimes²sometimes²
ageneverneversometimes²sometimes³
dobneverneversometimes⁴sometimes⁴
failureReasonneverneverneveralways

¹ Present unless failureReason is max-attempts-exceeded or fraudulent-activity-detected
² Present only if both age.low and age.high are available
³ Present only if both age.low and age.high are available AND failureReason isn't max-attempts-exceeded or fraudulent-activity-detected
⁴ Only included if includeDob=true query parameter is set AND available from the verification method

Example payloads

Webhook event examples

PASS status with age information

{
"eventType": "Verification.Result",
"data": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "PASS",
"method": "id-document",
"ageCategory": "adult",
"age": {
"low": 25,
"high": 25
},
"dob": "1998-05-15"
}
}

FAIL status with age information

{
"eventType": "Verification.Result",
"data": {
"id": "123e4567-e89b-12d3-a456-426614174001",
"status": "FAIL",
"method": "age-estimation-scan",
"failureReason": "age-criteria-not-met",
"age": {
"low": 16,
"high": 17
}
}
}

FAIL status without age information

{
"eventType": "Verification.Result",
"data": {
"id": "123e4567-e89b-12d3-a456-426614174002",
"status": "FAIL",
"failureReason": "max-attempts-exceeded"
}
}

API endpoint response examples

PENDING status

{
"id": "123e4567-e89b-12d3-a456-426614174003",
"status": "PENDING"
}

IN_PROGRESS status

{
"id": "123e4567-e89b-12d3-a456-426614174004",
"status": "IN_PROGRESS"
}

PASS status with age information (without DOB)

{
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "PASS",
"method": "id-document",
"ageCategory": "adult",
"age": {
"low": 25,
"high": 25
}
}

PASS status with DOB (includeDob = true)

{
"id": "123e4567-e89b-12d3-a456-426614174000",
"status": "PASS",
"method": "id-document",
"ageCategory": "adult",
"age": {
"low": 25,
"high": 25
},
"dob": "1998-05-15"
}

FAIL status with age information

{
"id": "123e4567-e89b-12d3-a456-426614174001",
"status": "FAIL",
"method": "age-estimation-scan",
"failureReason": "age-criteria-not-met",
"age": {
"low": 16,
"high": 17
},
"ageCategory": "digital-minor"
}

FAIL status without age information

{
"id": "123e4567-e89b-12d3-a456-426614174002",
"status": "FAIL",
"failureReason": "max-attempts-exceeded"
}

Implementation checklist

Webhook events

  • Handle both status types: PASS and FAIL (webhooks never send PENDING or IN_PROGRESS)
  • Check for presence of age object before accessing age.low or age.high
  • Use ageCategory for access control when status is PASS and ageCategory is present
  • Don't use ageCategory for FAIL status (it won't be present in webhook events)
  • Handle cases where method is absent (system-level failures)
  • Handle cases where age and ageCategory are absent (certain failure scenarios)
  • Validate dob format (YYYY-MM-DD) if present
  • Log failureReason for debugging
  • Don't grant access for FAIL status
  • Handle unknown failureReason values gracefully

API endpoint

  • Handle all status types: PENDING, IN_PROGRESS, PASS, and FAIL
  • For PENDING and IN_PROGRESS statuses, only expect id and status fields
  • Set includeDob=true query parameter if DOB data is needed (see GET /age-verification/get-status)
  • Check for presence of age object before accessing age.low or age.high
  • Use ageCategory for access control when status is PASS and ageCategory is present
  • Don't use ageCategory for access control when status is FAIL, even if present
  • Handle cases where method is absent (system-level failures)
  • Handle cases where age and ageCategory are absent (certain failure scenarios)
  • Validate dob format (YYYY-MM-DD) if present
  • Log failureReason for debugging
  • Don't grant access for FAIL status
  • Handle unknown failureReason values gracefully
  • Implement appropriate polling strategy for PENDING and IN_PROGRESS statuses

Implementation notes

AgeCategory behavior

The ageCategory field is only included when status is PASS in webhook events. This ensures that age category information is only provided when the verification is successful. Note that the API endpoint can include ageCategory for FAIL status in some cases, but you shouldn't use it for access control decisions.

Version history

  • 2024-12-05: Initial API contract document