Protocols
DCQL (Digital Credentials Query Language)
DCQL, the Digital Credentials Query Language, is how an OpenID4VP request states which credentials it wants and which claims from them. It replaced the earlier Presentation Exchange syntax in OpenID4VP 1.0, and it asks for a claim by name; it does not constrain what that claim's value may be.
Also called: DCQL, digital credentials query language, credential query
At a glance
- Introduced in
- OpenID for Verifiable Presentations 1.0
- Replaces
- Presentation Exchange, used by earlier drafts
- Asks for
- A claim by name, in a named credential and format
- Does not constrain
- The value of that claim
- Consequence
- Verification success is not the same as the answer being yes
What a query says
A DCQL query names credential sets and, within them, the claims wanted, along with the format and any document type or credential type filter. A verifier asking for proof of age over 18 from an mdoc names the doctype, the namespace and the element; asking from an SD-JWT VC names the credential type and the claim path.
It is deliberately narrow. The point is to ask for as little as answers the question, so the wallet can show the user a short and truthful consent screen.
The mistake worth writing down
DCQL asks for a claim. It does not require the claim to have a particular value. A wallet holding age_over_18 with the value false can satisfy a request for age_over_18 perfectly well, and the response it returns will verify: the signature is good, the disclosure is genuine, the credential is authentic. The answer is simply no.
So a verifier that treats "the presentation verified" as "the person is over 18" is wrong, and wrong in the direction that lets everyone through. The value that was disclosed has to be read. We shipped exactly this bug and only caught it against a real wallet, which is why it is in the glossary and not in a footnote.
There is a third outcome too. If a credential verifies but did not disclose the claim you asked for, you have neither a yes nor a no; you have a check that cannot be answered. Folding that into "no" is tempting and wrong, and it deserves its own state in your data model.
Check one yourself
Reading about it only gets you so far. These are free validators in Tessio Labs, no signup, and nothing you paste is stored.
Why it matters
Read the disclosed value, never the verification result alone. "Verified" and "over 18" are different facts, and conflating them fails open.
Give the unanswerable case its own state alongside yes and no. A credential that verified but disclosed nothing relevant isn't a refusal, and treating it as one hides a broken integration.
Frequently asked
Can I ask DCQL for "age_over_18 must be true"?
No. The query selects which claim is presented, not which value is acceptable. Evaluating the value is the verifier's job after the presentation arrives.
What happens if the wallet does not have the credential I asked for?
The user is told the request can't be satisfied, and you get no presentation at all, not an empty one. That's a different outcome from a presentation that arrives without the claim you wanted.
Is DCQL specific to the EU wallet?
No, it's part of OpenID4VP and format neutral. The EU wallet uses it, and so does anything else built on OpenID4VP 1.0.
Primary sources
This is a plain language explanation, not legal advice. Specifications and dates in this area move, so check anything you are going to rely on against the primary sources.
Keep reading
Age verification API
Or skip the theory and build against it
Tessio proves someone is over 18 from their EU Digital Identity Wallet and stores no personal data. Access is invite only while we onboard design partners. Tell us what you're building.