DCQL Queries
Digital Credentials Query Language, for specifying exactly which credentials and claims you need
DCQL (Digital Credentials Query Language) is the query format used in OID4VP v1. It lets you specify which credentials, claims, and trust constraints the wallet must satisfy.
Basic structure
{
"credentials": [
{
"id": "unique_id",
"format": "mso_mdoc",
"meta": { "doctype_value": "..." },
"claims": [
{ "path": ["namespace", "attribute"] }
]
}
]
}Credential query
Each credential entry describes one type of credential you'll accept:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique identifier for this credential query |
format | "mso_mdoc" | "dc+sd-jwt" | Yes | Credential format |
meta | object | No | Format-specific metadata |
claims | array | No | Specific claims to request |
trusted_authorities | array | No | Trust constraints (see Trusted Authorities) |
mDoc metadata
For mso_mdoc format:
{
"meta": {
"doctype_value": "eu.europa.ec.eudi.pid.1"
}
}SD-JWT metadata
For dc+sd-jwt format:
{
"meta": {
"vct_values": ["eu.europa.ec.eudi.pid.1"]
}
}Claims
Claims specify which attributes to request. The path format differs by credential format.
mDoc claims
For mDoc credentials, the path is [namespace, attribute]:
{
"claims": [
{ "path": ["eu.europa.ec.eudi.pid.1", "family_name"] },
{ "path": ["eu.europa.ec.eudi.pid.1", "given_name"] },
{ "path": ["eu.europa.ec.eudi.pid.1", "age_over_18"] }
]
}SD-JWT claims
For SD-JWT credentials, the path is [attribute]:
{
"claims": [
{ "path": ["family_name"] },
{ "path": ["given_name"] },
{ "path": ["age_over_18"] }
]
}Claim options
| Field | Type | Description |
|---|---|---|
path | string[] | Attribute path |
values | any[] | Acceptable values (the claim must match one) |
intent_to_retain | boolean | Signal that you intend to store this claim |
Value constraints
Request only credentials where age_over_18 is true:
{
"path": ["eu.europa.ec.eudi.pid.1", "age_over_18"],
"values": [true]
}Credential sets
When you accept multiple credential types, use credential_sets to define the logic:
{
"credentials": [
{ "id": "pid_mdoc", "format": "mso_mdoc", "meta": { "doctype_value": "eu.europa.ec.eudi.pid.1" } },
{ "id": "pid_sdjwt", "format": "dc+sd-jwt", "meta": { "vct_values": ["eu.europa.ec.eudi.pid.1"] } }
],
"credential_sets": [
{
"options": [["pid_mdoc"], ["pid_sdjwt"]],
"required": true
}
]
}This tells the wallet: "I need a PID: either mDoc or SD-JWT format is fine."
Complete example
{
"credentials": [
{
"id": "pid",
"format": "mso_mdoc",
"meta": { "doctype_value": "eu.europa.ec.eudi.pid.1" },
"claims": [
{ "path": ["eu.europa.ec.eudi.pid.1", "family_name"] },
{ "path": ["eu.europa.ec.eudi.pid.1", "given_name"] },
{ "path": ["eu.europa.ec.eudi.pid.1", "birth_date"] },
{
"path": ["eu.europa.ec.eudi.pid.1", "age_over_18"],
"values": [true],
"intent_to_retain": false
}
],
"trusted_authorities": [
{ "type": "aki", "values": ["MIGfMA0GCSqGSIb3DQEBAQUAA4GN"] }
]
}
]
}