DCQL query: Age Verification
When to use
Use this template when your service must know that a person passes an age threshold, and nothing more. The query asks for five boolean flags. Each flag answers one question, for example "is this person over 18?". The wallet does not disclose the birth date, the name, or the document number.
Ask only for the thresholds that your law or your policy needs. One flag is enough for most age gates. Every extra flag is extra personal data.
Template facts
Registry version: 2026.4.1.
| Fact | Value |
|---|---|
| Title | Age Verification |
| Purpose | Age Verification |
| Credential type (doctype) | eu.europa.ec.av.1 |
| Namespace | eu.europa.ec.av.1 |
| Format | mso_mdoc |
The registry holds one format for this template. There is no SD-JWT VC file and no JWT VC file.
Claims
Format mso_mdoc
{
"claims": [
{
"path": ["eu.europa.ec.av.1", "age_over_14"]
},
{
"path": ["eu.europa.ec.av.1", "age_over_16"]
},
{
"path": ["eu.europa.ec.av.1", "age_over_18"]
},
{
"path": ["eu.europa.ec.av.1", "age_over_21"]
},
{
"path": ["eu.europa.ec.av.1", "age_over_65"]
}
]
}
How to read the path arrays
For mso_mdoc, the path array holds exactly two elements:
- the namespace, here
eu.europa.ec.av.1; - the data element name, here the age flag.
The namespace and the doctype carry the same string in this template. They are
still two different fields. The doctype goes into meta.doctype_value. The
namespace goes into the first element of every path.
Use with the iGrant.io API
Create a presentation definition with
POST /v2/config/digital-wallet/openid/sdjwt/presentation-definition. Put the
claims into one entry of dcqlQuery.credentials[]. Give the entry an id, set
format to mso_mdoc, and set meta.doctype_value to the credential type.
mso_mdoc allows doctype_value only. The server refuses vct_values and
type_values for this format.
Set version to version_01.
{
"label": "Age gate at checkout",
"version": "version_01",
"responseType": "vp_token",
"responseMode": "direct_post",
"dcqlQuery": {
"credentials": [
{
"id": "age-verification",
"format": "mso_mdoc",
"meta": { "doctype_value": "eu.europa.ec.av.1" },
"claims": [
{ "path": ["eu.europa.ec.av.1", "age_over_18"] }
]
}
]
}
}
Do not use the label Age Verification. The server reserves that label for
an extension and refuses it. Give the definition a label that names your use,
for example Age gate at checkout.
Then send the verification request with the V3 send operation,
POST /v3/config/digital-wallet/openid/sdjwt/verification/send, and pass the
presentationDefinitionId of the record that you created. Read the disclosed
flags from presentation on the verification history record.
The igrantio-api-verifier skill holds the full operation reference: every
field of the presentation definition, every transport option, and the shape of
the verification history record.
Source is the registry
The iGrant.io verifiable data registry is the source of truth for this template. If this skill and the registry file disagree, the registry wins. Fetch the source directory before you rely on a claim path:
- https://github.com/decentralised-dataexchange/verifiable-data-registry/tree/main/presentationDefinitions/dcqlQuery/ageVerification
- Raw file: https://raw.githubusercontent.com/decentralised-dataexchange/verifiable-data-registry/main/presentationDefinitions/dcqlQuery/ageVerification/2026.4.1/mso_mdoc.schema.v1.json
Follow the registry and report the drift so this skill can be corrected.