Technical

Integrating the EU Proof-of-Age Attestation: A Developer's Guide to the eu.europa.ec.av.1 Namespace

The EU's age-verification issuer issues a 'Proof of Age' attestation in mso_mdoc format under the namespace eu.europa.ec.av.1, over OpenID4VCI. Here is what that namespace actually contains, how issuance works, and how to point your integration at the live reference issuer — with the caveat that it is a reference, not a production endpoint.

eIDAS Pro Team
June 26, 2026
11 min read
Integrating the EU Proof-of-Age Attestation: A Developer's Guide to the eu.europa.ec.av.1 Namespace

If you are integrating age verification against the EU's solution, one string will appear in your code more than any other: eu.europa.ec.av.1. It is the namespace of the "Proof of Age" attestation, and understanding what it is — and what it deliberately is not — is the foundation of a correct integration.

This guide is the practical counterpart to our conceptual breakdown of the EU age-verification app. Here we stay at the protocol and data-model level: the credential format, the issuance flow, and how to wire your code to the live reference issuer.

The attestation, precisely

The EU's official Age Verification Issuer is a (Q)EAA Provider — a provider of (qualified) electronic attestations of attributes, in the eIDAS 2.0 sense. It implements the Age Verification Specification and issues a "Proof of Age" attestation with these defining properties:

  • Format: mso_mdoc — the ISO/IEC 18013-5 mobile-document format, the same family used by mobile driving licences and the EUDI Wallet's PID. If you have read How eIDAS Verification Works, this is the credential format underneath it.
  • Namespace: eu.europa.ec.av.1. Every claim in the attestation is qualified by this namespace. Version is baked into the namespace itself — the trailing .1 — so a future breaking change becomes eu.europa.ec.av.2, and your code can branch on it.
  • Semantics: it confirms the holder is above a given age threshold without disclosing the date of birth. This is the entire point. The attestation answers "is this person over N?" and nothing more.

In eIDAS terms, this is an electronic attestation of attributes under Article 3(44) of the Regulation. That legal framing is not decoration — it is what lets a proof-of-age presentation carry legal weight across borders, the same way a cross-border verification of identity does.

Why a namespace instead of just "age ≥ 18"

Newcomers often ask why the EU wrapped something as simple as an over-18 boolean in a formal mdoc namespace. Three reasons, each of which saves you work later:

  1. Multiple thresholds, one model. Age gates are not all 18. Alcohol, gambling, certain content, and "child-directed service" rules use 16, 18, 21, and others. A namespaced attestation can express threshold claims uniformly rather than forcing each relying party to invent its own encoding.
  2. Verifiable provenance. Because the claim sits inside a signed mdoc, your verifier checks a signature and a trust chain — not a self-asserted value. The signature is what makes this fundamentally different from the age checkbox it replaces.
  3. Unlinkability by construction. The standard attestation is one-time-usable and issued in batches specifically so that repeated presentations cannot be correlated into a profile. We return to this below, because it is the most commonly over-claimed property of the system.

Issuance: OpenID4VCI

The issuer follows OpenID for Verifiable Credential Issuance (OpenID4VCI). If your team has worked with OpenID4VP for presentation, VCI is its issuance-side sibling: where VP is how a credential is presented to you, VCI is how it gets into the wallet in the first place.

The flow, at the level you need to reason about it:

  1. A user onboards to the age-verification app or wallet, proving their age once through a trusted source (an eID, or — since blueprint v2 — a passport or national ID card).
  2. The wallet runs an OpenID4VCI exchange with the issuer to obtain a batch of Proof-of-Age attestations.
  3. Each attestation in the batch is one-time-usable. As the user presents proofs over time, the wallet draws down the batch and refreshes as needed.

As an integrating relying party you generally do not operate the issuance side — that is the (Q)EAA Provider's job. But understanding it explains the properties you will observe at presentation time: short-lived, single-use proofs, with no stable identifier to key off.

The live reference issuer — and the caveat that matters

The EU publishes a working reference implementation. The issuer back end (av-srv-web-issuing-avw-py) is open source under the official EU Digital Identity Wallet GitHub organisation, copyright the European Commission, and there is a live, publicly hosted reference issuer you can exercise during development.

Read this carefully: it is a reference and testing implementation. It is explicitly not a production-complete, citizen-grade issuer. Use it to validate your integration, your credential parsing, and your presentation flow. Do not build a launch plan that assumes it is the production endpoint your real users will hit — that endpoint will be the national age-verification apps and wallets the front-runner Member States are rolling out. Treat the reference issuer the way you would any sandbox: invaluable for building, not a production dependency.

The privacy claim, stated accurately

Here is where careful engineers separate themselves from marketing copy. You will read that the EU age-verification solution uses Zero-Knowledge Proofs (ZKP) so a relying party learns only a yes/no answer with no possibility of correlation. Be precise:

  • What is solid: the standard mdoc attestation is one-time-usable and batch-issued precisely to frustrate linkability. The proof reveals over-threshold status, not date of birth or identity. That is a genuine, shipped privacy property.
  • What to be careful with: ZKP is described as a supported, preferred proof type in the verifier guidance — not as a universally shipped, fully non-correlatable guarantee specified in some annex. Do not write documentation asserting "the system is zero-knowledge, therefore correlation is impossible." Write: "unlinkability is achieved through one-time-use, batch-issued proofs; ZKP is supported as an enhanced proof type."

This is not pedantry. If your compliance story claims a cryptographic guarantee the deployed system does not yet uniformly provide, that is the claim an auditor will pull on. The honest version is still an excellent privacy story — see Privacy-First Age Verification for how we frame it.

A minimal integration checklist

StepWhat you doNotes
1Decide your threshold(s)18, 16, 21 — map each gate to a claim in eu.europa.ec.av.1
2Implement the verifier (presentation) sideSupport the DC API / OpenID4VP request flow
3Parse the mso_mdoc Proof-of-AgeValidate signature and namespace version
4Validate against the trust listAnchor to the EU Age Verification Trusted List (covered in our companion post)
5Treat proofs as single-useDo not store or replay; do not derive an identifier
6Register your intended-use scopeUnder IR 2025/848 — request only proof-of-age, nothing more

Step 6 connects this developer task back to the relying party registration and WRPAC obligations. A relying party that registers for proof-of-age only is structurally incapable of over-asking — which is the cleanest possible answer to a data-protection regulator.

The bottom line

The eu.europa.ec.av.1 namespace is small in size and large in consequence. It is an mso_mdoc, Article 3(44) attestation, issued over OpenID4VCI, that proves an age threshold and nothing else. Build against the live reference issuer to get your parsing and presentation flow right — but treat it as a sandbox, not production. And when you document the privacy properties, describe what is shipped (one-time-use, batch-issued, threshold-only) rather than what is aspirational (universal ZKP). Get those two things right and your integration will survive contact with both real wallets and real auditors.

This post reflects the EU Age Verification specification and reference implementation as of June 2026. The reference issuer is a testing implementation, not production. Verify the credential schema against the official issuer repository before building.

Share this article

Help others learn about eIDAS verification