Skip to main content

Anonymous Age Credential

The Anonymous Age Credential lets your users prove their age to third parties — for example, that they are over 18 — without sharing any personal information. No name, no ID number, no date of birth. Just a simple yes/no answer to an age question, stored in their digital wallet.

As an issuer, your only job is to create an offer and show the user a QR code or link. The user's wallet and identity provider handle everything else automatically.

What the credential contains

The credential holds a set of age checkpoints. Each one is a simple true/false answer that the user can share independently:

Age checkpointWhat it means
age_over_13User is 13 or older
age_over_15User is 15 or older
age_over_16User is 16 or older
age_over_18User is 18 or older
age_over_21User is 21 or older
age_over_23User is 23 or older
age_over_25User is 25 or older
age_over_27User is 27 or older
age_over_60User is 60 or older
age_over_65User is 65 or older
age_over_67User is 67 or older
age_over_69User is 69 or older

The user chooses which checkpoints to share with each verifier. A shop asking "are you over 18?" only sees that one answer — nothing else.

The credential is valid for 6 months from the date it is issued.

Privacy by design

  • No personal data is stored or transmitted. The user's date of birth comes from their identity provider's authentication token. The CoreAPI uses it to compute the age checkpoints on the fly and never writes it to the credential.
  • Each offer is single-use. The link you create can only be claimed once and expires after 5 minutes if unused.
  • The user is not tracked. The credential is tied to the user's own wallet key, not to any identifier held by the issuer.

Who can be an issuer?

Any company or authority that has been approved and onboarded by dewa can issue this credential. In the CoreAPI, approved issuers are called tenants.

Becoming a tenant involves a short approval process where dewa reviews your organization and grants you access. As part of that process you are explicitly enabled for the specific credential types you need — in this case the Anonymous Age Credential. You cannot issue a credential type that has not been enabled for your account.

See Onboarding to get started.

How trust works

When a user's wallet receives a credential, it needs to know the credential is genuine and came from a legitimate source. Here is how that is established:

  1. dewa vouches for you. Your organization has been reviewed and approved by dewa before you can issue anything.
  2. Your identity is published openly. Each issuer has a publicly accessible identity document (a DID document) hosted at a well-known URL. It contains your public signing key so anyone can verify credentials you have issued.
  3. Every credential is digitally signed. The CoreAPI signs each credential with your private key. The user's wallet checks this signature against your published identity before accepting the credential.

This means the user's wallet can independently confirm that the credential came from you — no central registry or intermediary needed.

How to issue a credential

The flow has four steps, but as an issuer you only need to implement step 1. Steps 2–4 are handled automatically by the user's wallet and identity provider.

The age checkpoints are calculated from the date_of_birth claim in the user's identity token — the token they receive when they authenticate with the identity provider connected to your tenant. You do not supply the date of birth yourself.

Step 1 — Create an offer

Call the CoreAPI to create a one-time offer. You need to be authenticated as a tenant.

POST /credential-offer
Authorization: Bearer {your_access_token}
Content-Type: application/json

{
"credential_configuration_id": "dk.e-boks.AnonymousAgeCredential.1",
"offer_expires_at": "2026-04-15T14:00:00Z"
}
FieldRequiredNotes
credential_configuration_idYesAlways dk.e-boks.AnonymousAgeCredential.1 for this credential type
offer_expires_atYesWhen the offer should expire — must be a future date and time

The API returns a link:

"openid-credential-offer://?credential_offer_uri=https://issuer.example.com/credential-offer/3fa85f64-..."

Convert this link into a QR code or send it as a deep link to the user. Once they scan or tap it, their wallet takes over and completes the process automatically. The offer expires after 5 minutes if not claimed.

Steps 2–4 — Handled by the wallet and identity provider

The user's wallet fetches the offer details, then authenticates with the identity provider connected to your tenant. The identity provider issues a token that contains the user's date_of_birth. The CoreAPI reads that claim from the token, calculates the age checkpoints, and issues the credential into the user's wallet. No further action is needed from your side.

Common errors

SituationWhat happens
offer_expires_at is in the past400 — request rejected
Your access token is missing or expired401 — unauthorized
Your account is not enabled for this credential type403 — contact dewa to have it enabled
The user's identity token is missing a valid date_of_birth claim400 — credential issuance fails; ensure your identity provider includes this claim

For full error response details see Error Handling.