Creating Verification Queries
A verification query is a named, reusable statement of what you want a holder to present. You create one against the credential verification service, and every presentation you request names it by id.
Two names, one nesting
A verification query is ours: the object you create and address by verification_query_id. Inside it sits a
DCQL query — Digital Credentials Query
Language,
the part of OID4VP that expresses which credentials and claims you are asking for. So the thing you create is
a verification query; the thing you write inside it is a DCQL query.
Hold as many verification queries as you have distinct things to ask for. Each is created once and reused across sessions.
What is a DCQL query?
A DCQL query is a structured representation of the data the wallet should present to the verifier during the
presentation protocol. In the example below it instructs the wallet to include
studentId, dateOfBirth and enrollmentYear in a verifiable presentation:
DCQL query example:
{
"credentials": [ // (1)!
{
"id": "studentCard", // (2)!
"format": "jwt_vc_json-ld", // (3)!
"meta": {}, // (4)!
"claims": [ // (5)!
{
"id": "studentId", // (6)!
"path": [ "credentialSubject", "studentId" ] // (7)!
},
{
"id": "dateOfBirth",
"path": [ "credentialSubject", "dateOfBirth" ]
},
{
"id": "enrollmentYear",
"path": [ "credentialSubject", "enrollmentYear" ]
}
]
}
]
}
- This is an array of credential queries. Each credential query specifies the type of information (claims) the wallet must present for this requested credential. A single DCQL query can contain multiple credential queries, and the wallet must present all of them in the presentation.
- A string that serves as an identifier for the credential query. This value is used when the wallet prepares the presentation, and therefore must not conflict with other IDs.
- The format of the requested credential.
- Optional. An object defining additional properties requested by the verifier that apply to the metadata and
validity data of the credential. Only
idandformatare required on a credential query, so leavemetaout entirely if you are not constraining anything. - An array of
Claim Queriesspecifying which claims the wallet must present. - A string that serves as an identifier for the claim query. This is an optional field, but it can be useful for keeping track of claims and their values. If used, the value must not conflict with other IDs.
- An array of strings specifying a path to the requested claim value within a credential.
Writing the DCQL query
The overall structure of your own DCQL query must be updated and maintained. Therefore, use the example above as a guideline and starting point.
The main part of a DCQL query are the list of Claims Queries that specify the information to be
requested from the wallet. Within each Claim Query object, you must define path and optionally an id (recommended).
The path is an array of strings specifying a path to where the information is located within the credential.
{
"id": "dateOfBirth",
"path": ["credentialSubject", "dateOfBirth"]
}
Add these object blocks into the claims array in the JSON structure separated by a comma.
Creating the verification query
Register the DCQL query with the service by calling POST /verification-query/create. You can also try it from
the API specification a running service serves.
The DCQL query goes inside a dcql_query field, alongside an optional uri_prefix:
curl -X 'POST' \
'{credential_verification_service_URL}/verification-query/create' \
-H 'Authorization: Bearer {your API key}' \
-H 'Content-Type: application/json' \
-d '{
"dcql_query": {
"credentials": [
{
"id": "studentCard",
"format": "jwt_vc_json-ld",
"claims": [
{
"id": "studentId",
"path": ["credentialSubject", "studentId"]
},
{
"id": "dateOfBirth",
"path": ["credentialSubject", "dateOfBirth"]
},
{
"id": "enrollmentYear",
"path": ["credentialSubject", "enrollmentYear"]
}
]
}
]
}
}'
The DCQL query is not the request body
dcql_query is required, and the credential query array goes inside it. Posting the bare
{ "credentials": [...] } fails.
uri_prefix is the other field this endpoint accepts, and it belongs to the verification query rather than to
the DCQL query inside it. It sets the scheme of the deep link that
starting a session from this query returns, and defaults to haip-vp://. Set it only
to match a wallet that registers a different scheme — the issuer's equivalent is credentialOfferPrefix.
The service returns 201 - created, and the response body is the new verification query's id as plain text.
Keep it: that id is what you pass as verification_query_id when you
request a presentation.
You can read a verification query back with GET /verification-query/{verification_query_id}.
What's Next
- Request a presentation: Start a session from this query.
- Receive verified data: Get the results pushed to your application.