iGrant.io OpenID4VC API - Verifier
When to use
Use this skill when your organisation asks a holder for credentials. It covers
the 18 operations of the Verifier group: the verifier global configuration,
presentation definitions, transaction data templates, the V3 verification
request, the verification history, the Digital Credentials API response, and
revalidation.
Use it when you must:
- write a DCQL query and store it as a presentation definition;
- send an Authorization Request and get the
openid4vp:// URI and the
correlation id;
- read the disclosed claims and the
verified result;
- take a Digital Credentials API response from the browser;
- check a finished exchange again after a revocation.
For the wallet side of a presentation, read igrantio-api-holder. For issuance,
read igrantio-api-issuer.
Protocol scope
- The verifier implements OpenID4VP 1.0. Set
version to version_01
on the presentation definition. iso18013_7_annex_c selects
the ISO 18013-7 Annex C profile for mDoc credentials over the Digital
Credentials API.
- DCQL is the only way to give the credential requirements. Presentation
Exchange is not a supported surface. A DCQL query cannot be sent inline with
the verification request: store it in a presentation definition and reference
it with
presentationDefinitionId.
- Send a verification request with the V3 operation
(
POST /v3/config/digital-wallet/openid/sdjwt/verification/send). Read the
history with the V3 operations. Draft protocol versions are not a supported
surface.
Authentication
Send the API key in the Authorization header with the ApiKey prefix and a
space:
Authorization: ApiKey <your-api-key>
Demo base URL: https://demo-api.igrant.io. The bundle also lists
https://api.igrant.io (production) and https://staging-api.igrant.io.
The API key stays on your server. The browser never holds it.
Endpoint reference
Presentation definitions
| Method |
Path |
Purpose |
Documentation |
POST |
/v2/config/digital-wallet/openid/sdjwt/presentation-definition |
Create a presentation definition that holds a DCQL query and the transport settings. |
Create presentation definition |
GET |
/v2/config/digital-wallet/openid/sdjwt/presentation-definition/{presentationDefinitionId} |
Read one presentation definition. |
Read presentation definition |
PUT |
/v2/config/digital-wallet/openid/sdjwt/presentation-definition/{presentationDefinitionId} |
Update a presentation definition. |
Update presentation definition |
DELETE |
/v2/config/digital-wallet/openid/sdjwt/presentation-definition/{presentationDefinitionId} |
Delete a presentation definition. |
Delete presentation definition |
GET |
/v2/config/digital-wallet/openid/sdjwt/presentation-definitions |
List presentation definitions. Filter with search, sortOrder, transactionDataType, skipCounts, offset and limit. |
List presentation definition |
GET |
/v2/config/digital-wallet/openid/sdjwt/presentation-definition/templates |
List the ready-made presentation definition templates. |
List presentation definition templates |
GET |
/v2/config/digital-wallet/openid/sdjwt/transaction-data-definitions |
List the transaction data templates and the JSON Schema of each type. |
List transaction data templates |
Verification
| Method |
Path |
Purpose |
Documentation |
POST |
/v3/config/digital-wallet/openid/sdjwt/verification/send |
Send an OpenID4VP Authorization Request from a stored presentation definition. |
Send verification request |
GET |
/v3/config/digital-wallet/openid/sdjwt/verification/history |
List the verification history. Filter with status, presentationDefinitionId, individualId, mapperId, holderDid, responseCode, requestPending, verificationFailed, expired, search, sortOrder, offset and limit. |
List verification history |
GET |
/v3/config/digital-wallet/openid/sdjwt/verification/history/{presentationExchangeId} |
Read one verification exchange record. |
Read verification history |
POST |
/v2/config/digital-wallet/openid/sdjwt/verification/history/{presentationExchangeId}/receive |
Take a Digital Credentials API response from the browser. |
Receive DC API verification response |
POST |
/v2/config/digital-wallet/openid/sdjwt/verification/history/{presentationExchangeId}/revalidate |
Check the signatures, the revocation status, and the trust chain again. |
Revalidate verification |
DELETE |
/v2/config/digital-wallet/openid/sdjwt/verification/history/{presentationExchangeId} |
Delete one verification exchange record. |
Delete verification history |
Verifier global configuration
supportCredentialEncryption is mandatory on the verifier global
configuration. Set it to true before you use a direct_post.jwt or
dc_api.jwt response mode. presentationRequestExpiresIn is the request
lifetime in seconds, with a smallest value and a default of 3600.
Key fields
Create presentation definition
POST /v2/config/digital-wallet/openid/sdjwt/presentation-definition
label is mandatory: 3 to 100 characters. The labels that extensions reserve
are refused, for example Age Verification, Document Signing and
Know-Your-Customer (KYC).
dcqlQuery is mandatory when responseType is vp_token or
device_response. Do not send it when responseType is id_token.
Transport fields:
| Field |
Values |
Note |
version |
version_01, iso18013_7_annex_c |
version_01 is OpenID4VP 1.0. iso18013_7_annex_c needs trustAnchor set to x509 and expectedOrigins. |
responseType |
vp_token, id_token, device_response |
Default vp_token. device_response is only for iso18013_7_annex_c. |
responseMode |
direct_post, direct_post.jwt, dc_api, dc_api.jwt |
Default direct_post. The .jwt variants return an encrypted JWE. |
clientIdScheme |
redirect_uri, did, verifier_attestation, x509_san_dns, x509_hash |
Default redirect_uri. Send null for iso18013_7_annex_c. With the DC API response modes, redirect_uri is only a logical identifier. |
trustAnchor |
did:key, x509 |
Default did:key. |
kid |
string |
The verifier key. The organisation key is used when you send no value. The key must be valid when dcApiRequestType is signed. |
dcApiRequestType |
signed, unsigned |
Only with dc_api or dc_api.jwt. A missing value means unsigned for dc_api and signed for dc_api.jwt. Use signed in production. |
expectedOrigins |
array of strings |
Mandatory when the effective dcApiRequestType is signed, and for iso18013_7_annex_c. The wallet ignores it for an unsigned request. |
encryptedResponseEncValuesSupported |
A128CBC-HS256, A128GCM, A256GCM |
Mandatory for direct_post.jwt, and the verifier global configuration must permit encryption. An empty stored value falls back to all three. dc_api.jwt ignores this field and always uses A256GCM. |
directPostRedirectUri |
string |
Only for direct_post. The server refuses it for direct_post.jwt, and it has no meaning for the DC API modes. |
scope |
string |
For a scope-based presentation request. |
transactionDataDefinitionType |
payment_data, payment, login_risk_transaction, login_risk_transaction_non_ts12, account_access, emandate, data_agreement_record, data_disclosure_agreement_record, qes_data |
Selects the JSON Schema that validates the transactionData of the verification request. Mandatory when the DCQL query asks for a Payment Wallet Attestation, a QESAC credential, or an SCA attestation. |
The DCQL query
dcqlQuery holds a mandatory credentials array with at least one entry, and an
optional top-level credential_sets array.
Each entry of dcqlQuery.credentials[] needs id and format:
id - the identifier that credential_sets and the presentation response use.
Use letters, digits, spaces, _ and -. The server does not apply this check
to the iso18013_7_annex_c version.
format - dc+sd-jwt, vc+sd-jwt, vp+sd-jwt, jwt_vc_json, jwt_vc or
mso_mdoc.
meta - the format gates the keys. The server refuses a key that the format
does not allow:
format |
Allowed meta keys |
mso_mdoc |
doctype_value only |
dc+sd-jwt |
vct_values or type_values |
jwt_vc_json |
type_values only; vct_values is refused |
vc+sd-jwt, vp+sd-jwt, jwt_vc |
none - leave meta out |
vct_values is an array of accepted vct strings. type_values is an array
of type sets: the credential must hold every type of at least one set.
doctype_value is a single docType string, for example
org.iso.18013.5.1.mDL.
claims - the claims that you ask for. Leave it out to ask for the whole
credential. Each item holds id (needed when you use claim_sets), path,
and an optional values array that limits the accepted values. For
mso_mdoc, path holds two elements: the namespace and the data element, for
example ["org.iso.18013.5.1", "family_name"]. For jwt_vc_json, path
starts with credentialSubject.
claim_sets - alternative sets of claim id values. The wallet satisfies the
first set that it can. Send it only together with a non-empty claims array.
require_cryptographic_holder_binding - true when the credential must prove
that the holder owns it.
multiple - true when the wallet can return more than one credential for
this query.
trusted_authorities - the issuers that you trust for this query. Each entry
holds type (for example etsi_tl for an ETSI trusted list, or aki for an
authority key identifier) and values.
Each entry of credential_sets[] holds a mandatory options array with at least
one combination. Each combination is an array of credential query identifiers.
required says whether the wallet must satisfy one of the options, and purpose
gives the reason. purpose accepts a string, a number, or an object.
{
"label": "Verify age over 18",
"version": "version_01",
"responseType": "vp_token",
"responseMode": "direct_post",
"dcqlQuery": {
"credentials": [
{
"id": "age-attestation",
"format": "mso_mdoc",
"meta": { "doctype_value": "eu.europa.ec.av.1" },
"claims": [
{ "path": ["eu.europa.ec.av.1", "age_over_18"] }
]
}
]
}
}
Send a verification request
POST /v3/config/digital-wallet/openid/sdjwt/verification/send
presentationDefinitionId is the only mandatory field. The server reads the DCQL
query, the response mode, the transaction data template, and the DC API settings
from that record. A value shorter than three characters is ignored, and the
server then answers with HTTP 400, because no requirements are left.
| Field |
Note |
requestByReference |
Default false. true passes the Authorization Request with the request_uri parameter. Use it for a large request. |
transactionData |
Send it when, and only when, the presentation definition sets a transactionDataDefinitionType. The server answers HTTP 400 in both mismatched cases. The structure must follow the JSON Schema of that type. |
nonce |
The server makes one when you send no value. V3 only. |
urlPrefix |
Scheme prefix of the deep link in vpTokenQrCode. Default openid4vp://. V3 only. |
individualId / mapperId |
Send the request as a push notification to the device of that individual. Do not send both. V3 only. |
signatureStamp / signatureCoordinate |
Signed PDF options. signatureCoordinate holds exactly four integers, [x1, y1, x2, y2], in points. V3 only. |
dataAgreement |
The terms of this verification exchange. V3 only. |
The response holds verificationHistory. Fields to read:
presentationExchangeId - the correlation id. id holds the same value.
vpTokenQrCode - the openid4vp:// URI. Render it as a QR code or open it as
a deep link.
status - request_sent, request_received, presentation_pending or
presentation_acked.
verified - the boolean result.
presentation - the disclosed claims, as an array.
vpTokenResponse - an array. A non-empty value means that the holder answered.
presentationValidity - the per-credential validity results.
responseMode, which on a record can also hold iar-post or iar-post.jwt,
and responseType (vp_token, id_token, device_response).
dcApiProtocol - openid4vp-v1-unsigned, openid4vp-v1-signed or
org-iso-mdoc, and dcApiRequest, which holds the ready-made
chrome.digital and safari.digital request objects.
requestExpired, requestExpiryTime, nonce, requiresEncryption,
idToken, idTokenDecoded, transactionData, transactionDataBase64,
files (each with credentialId, signedFile, unsignedFile, error,
errorDescription).
The read verification history operation returns the same record shape.
Receive a Digital Credentials API response
POST /v2/config/digital-wallet/openid/sdjwt/verification/history/{presentationExchangeId}/receive
The body takes one of two shapes:
{ "response": "<string>" } - use it for dc_api.jwt, where the string is the
JWE compact serialization (five base64url segments separated by .) that the
wallet returned. Use it also for dc_api when the payload is a JSON-encoded
string whose decoded form is {"vp_token": { ... }}.
{ "vp_token": { ... } } - use it for dc_api when the browser returns the
parsed JSON object. The object maps each DCQL credential query identifier to
the Verifiable Presentation of the wallet. The encoding of each presentation
follows the credential format.
Revalidate a verification
POST /v2/config/digital-wallet/openid/sdjwt/verification/history/{presentationExchangeId}/revalidate
has no request body; the server discards one if you send it. It checks the
credential signatures, the revocation status, and the trust chain again, writes
the new presentationValidity and verified values, and returns the full
record. Every other property stays the same.
The path is /v2, but the response holds the V3 record shape:
vpTokenResponse and presentation are arrays, and the V3-only properties are
present. This is the only V2 verification operation that answers with the V3
shape. The server does not compute requestExpired here; read the record with
the V3 read operation to get a current value.
Sandbox call style
Every Verifier operation except the list presentation definition templates
operation carries the optional X-SandboxOrgId header.
- With a bearer access token, send
X-SandboxOrgId: <sandboxOrgId>. The
service then runs the call against the wallet of that sandbox organisation and
not against the main wallet. Leave the header out to use the main wallet.
- With an API key, the header does nothing. The service takes the sandbox
organisation from the key. Bind the key first with
PUT /v2/config/admin/apikey/{apiKeyId}/sandbox-org.
X-SubwalletId is the deprecated name of the header. The service still accepts
it, and X-SandboxOrgId wins when you send both.
- The sandbox organisation must exist, must belong to your organisation, and must
be deployed. Any other identifier fails with HTTP 400.
Read igrantio-api-sandboxes for the sandbox organisation lifecycle.
Cross-references
igrantio-ows-overview - architecture, glossary, and the shared contracts.
igrantio-api-holder - the wallet that answers the Authorization Request.
igrantio-api-issuer - the issuance side of the same organisation.
igrantio-api-key-management - the verifier key that kid names, and the
X.509 material for x509_san_dns, x509_hash and iso18013_7_annex_c.
igrantio-api-trust-anchor - the trusted lists behind trusted_authorities.
igrantio-api-webhooks - the presentation events that tell you when the
holder answered.
igrantio-api-sandboxes - the sandbox organisation lifecycle.
Documentation is the source of truth
This skill mirrors the iGrant.io OpenID4VC API documentation. If this skill and
the linked documentation disagree, the documentation wins. Before you rely
on a payload shape, fetch the linked page, or the raw specification at
https://docs.igrant.io/openapispecifications/oid4vc.yaml, and check for
updates. Follow the documentation and report the drift so this skill can be
corrected.
1---2name: igrantio-api-verifier3description: Verifier group of the iGrant.io OpenID4VC API: create presentation definitions that hold a DCQL query (credential queries, claim sets, credential sets, trusted authorities, transaction data templates), send an OpenID4VP 1.0 Authorization Request with the V3 send operation, read and list the verification history, receive a Digital Credentials API response, revalidate a finished exchange, and delete a verification record. Use this skill when you build the relying-party side of an EUDI Wallet (EUDIW) or European Business Wallet (EUBW) integration, or whenever you need the exact verifier path, DCQL field, or enum value.4license: Apache-2.05---67# iGrant.io OpenID4VC API - Verifier89## When to use10Use this skill when your organisation asks a holder for credentials. It covers11the 18 operations of the **Verifier** group: the verifier global configuration,12presentation definitions, transaction data templates, the V3 verification13request, the verification history, the Digital Credentials API response, and14revalidation.1516Use it when you must:17- write a DCQL query and store it as a presentation definition;18- send an Authorization Request and get the `openid4vp://` URI and the19 correlation id;20- read the disclosed claims and the `verified` result;21- take a Digital Credentials API response from the browser;22- check a finished exchange again after a revocation.2324For the wallet side of a presentation, read `igrantio-api-holder`. For issuance,25read `igrantio-api-issuer`.2627## Protocol scope28- The verifier implements **OpenID4VP 1.0**. Set `version` to `version_01`29 on the presentation definition. `iso18013_7_annex_c` selects30 the ISO 18013-7 Annex C profile for mDoc credentials over the Digital31 Credentials API.32- **DCQL is the only way to give the credential requirements.** Presentation33 Exchange is not a supported surface. A DCQL query cannot be sent inline with34 the verification request: store it in a presentation definition and reference35 it with `presentationDefinitionId`.36- Send a verification request with the **V3** operation37 (`POST /v3/config/digital-wallet/openid/sdjwt/verification/send`). Read the38 history with the V3 operations. Draft protocol versions are not a supported39 surface.4041## Authentication42Send the API key in the `Authorization` header with the `ApiKey` prefix and a43space:4445```46Authorization: ApiKey <your-api-key>47```4849Demo base URL: `https://demo-api.igrant.io`. The bundle also lists50`https://api.igrant.io` (production) and `https://staging-api.igrant.io`.51The API key stays on your server. The browser never holds it.5253## Endpoint reference5455### Presentation definitions5657| Method | Path | Purpose | Documentation |58| --- | --- | --- | --- |59| `POST` | `/v2/config/digital-wallet/openid/sdjwt/presentation-definition` | Create a presentation definition that holds a DCQL query and the transport settings. | [Create presentation definition](https://docs.igrant.io/docs/openid4vc-api/config-digital-wallet-open-id-presentation-definition/) |60| `GET` | `/v2/config/digital-wallet/openid/sdjwt/presentation-definition/{presentationDefinitionId}` | Read one presentation definition. | [Read presentation definition](https://docs.igrant.io/docs/openid4vc-api/config-read-digital-wallet-open-id-presentation-definition/) |61| `PUT` | `/v2/config/digital-wallet/openid/sdjwt/presentation-definition/{presentationDefinitionId}` | Update a presentation definition. | [Update presentation definition](https://docs.igrant.io/docs/openid4vc-api/config-update-digital-wallet-open-id-presentation-definition/) |62| `DELETE` | `/v2/config/digital-wallet/openid/sdjwt/presentation-definition/{presentationDefinitionId}` | Delete a presentation definition. | [Delete presentation definition](https://docs.igrant.io/docs/openid4vc-api/config-delete-digital-wallet-open-id-presentation-definition/) |63| `GET` | `/v2/config/digital-wallet/openid/sdjwt/presentation-definitions` | List presentation definitions. Filter with `search`, `sortOrder`, `transactionDataType`, `skipCounts`, `offset` and `limit`. | [List presentation definition](https://docs.igrant.io/docs/openid4vc-api/config-list-digital-wallet-open-id-presentation-definition/) |64| `GET` | `/v2/config/digital-wallet/openid/sdjwt/presentation-definition/templates` | List the ready-made presentation definition templates. | [List presentation definition templates](https://docs.igrant.io/docs/openid4vc-api/config-list-digital-wallet-open-id-presentation-definition-templates/) |65| `GET` | `/v2/config/digital-wallet/openid/sdjwt/transaction-data-definitions` | List the transaction data templates and the JSON Schema of each type. | [List transaction data templates](https://docs.igrant.io/docs/openid4vc-api/config-list-digital-wallet-open-id-transaction-data-templates/) |6667### Verification6869| Method | Path | Purpose | Documentation |70| --- | --- | --- | --- |71| `POST` | `/v3/config/digital-wallet/openid/sdjwt/verification/send` | Send an OpenID4VP Authorization Request from a stored presentation definition. | [Send verification request](https://docs.igrant.io/docs/openid4vc-api/config-create-digital-wallet-open-id-verification-request-v-3/) |72| `GET` | `/v3/config/digital-wallet/openid/sdjwt/verification/history` | List the verification history. Filter with `status`, `presentationDefinitionId`, `individualId`, `mapperId`, `holderDid`, `responseCode`, `requestPending`, `verificationFailed`, `expired`, `search`, `sortOrder`, `offset` and `limit`. | [List verification history](https://docs.igrant.io/docs/openid4vc-api/config-list-digital-wallet-open-id-verification-history-v-3/) |73| `GET` | `/v3/config/digital-wallet/openid/sdjwt/verification/history/{presentationExchangeId}` | Read one verification exchange record. | [Read verification history](https://docs.igrant.io/docs/openid4vc-api/config-read-digital-wallet-open-id-verification-history-v-3/) |74| `POST` | `/v2/config/digital-wallet/openid/sdjwt/verification/history/{presentationExchangeId}/receive` | Take a Digital Credentials API response from the browser. | [Receive DC API verification response](https://docs.igrant.io/docs/openid4vc-api/config-receive-digital-wallet-open-id-dc-api-response/) |75| `POST` | `/v2/config/digital-wallet/openid/sdjwt/verification/history/{presentationExchangeId}/revalidate` | Check the signatures, the revocation status, and the trust chain again. | [Revalidate verification](https://docs.igrant.io/docs/openid4vc-api/config-revalidate-digital-wallet-open-id-verification/) |76| `DELETE` | `/v2/config/digital-wallet/openid/sdjwt/verification/history/{presentationExchangeId}` | Delete one verification exchange record. | [Delete verification history](https://docs.igrant.io/docs/openid4vc-api/config-delete-digital-wallet-open-id-verification-history/) |7778### Verifier global configuration7980| Method | Path | Purpose | Documentation |81| --- | --- | --- | --- |82| `POST` | `/v2/config/digital-wallet/openid/verifier/global-configuration` | Create the verifier global configuration. | [Create verifier global configuration](https://docs.igrant.io/docs/openid4vc-api/config-create-digital-wallet-open-id-verifier-global-configuration/) |83| `GET` | `/v2/config/digital-wallet/openid/verifier/global-configuration/{globalConfigurationId}` | Read the verifier global configuration. | [Read verifier global configuration](https://docs.igrant.io/docs/openid4vc-api/config-read-digital-wallet-open-id-verifier-global-configuration/) |84| `PUT` | `/v2/config/digital-wallet/openid/verifier/global-configuration/{globalConfigurationId}` | Update the verifier global configuration. | [Update verifier global configuration](https://docs.igrant.io/docs/openid4vc-api/config-update-digital-wallet-open-id-verifier-global-configuration/) |85| `DELETE` | `/v2/config/digital-wallet/openid/verifier/global-configuration/{globalConfigurationId}` | Delete the verifier global configuration. | [Delete verifier global configuration](https://docs.igrant.io/docs/openid4vc-api/config-delete-digital-wallet-open-id-verifier-global-configuration/) |86| `GET` | `/v2/config/digital-wallet/openid/verifier/global-configurations` | List the verifier global configuration. | [List verifier global configuration](https://docs.igrant.io/docs/openid4vc-api/config-list-digital-wallet-open-id-verifier-global-configuration/) |8788`supportCredentialEncryption` is mandatory on the verifier global89configuration. Set it to `true` before you use a `direct_post.jwt` or90`dc_api.jwt` response mode. `presentationRequestExpiresIn` is the request91lifetime in seconds, with a smallest value and a default of 3600.9293## Key fields9495### Create presentation definition96`POST /v2/config/digital-wallet/openid/sdjwt/presentation-definition`9798`label` is mandatory: 3 to 100 characters. The labels that extensions reserve99are refused, for example `Age Verification`, `Document Signing` and100`Know-Your-Customer (KYC)`.101102`dcqlQuery` is mandatory when `responseType` is `vp_token` or103`device_response`. Do not send it when `responseType` is `id_token`.104105Transport fields:106107| Field | Values | Note |108| --- | --- | --- |109| `version` | `version_01`, `iso18013_7_annex_c` | `version_01` is OpenID4VP 1.0. `iso18013_7_annex_c` needs `trustAnchor` set to `x509` and `expectedOrigins`. |110| `responseType` | `vp_token`, `id_token`, `device_response` | Default `vp_token`. `device_response` is only for `iso18013_7_annex_c`. |111| `responseMode` | `direct_post`, `direct_post.jwt`, `dc_api`, `dc_api.jwt` | Default `direct_post`. The `.jwt` variants return an encrypted JWE. |112| `clientIdScheme` | `redirect_uri`, `did`, `verifier_attestation`, `x509_san_dns`, `x509_hash` | Default `redirect_uri`. Send `null` for `iso18013_7_annex_c`. With the DC API response modes, `redirect_uri` is only a logical identifier. |113| `trustAnchor` | `did:key`, `x509` | Default `did:key`. |114| `kid` | string | The verifier key. The organisation key is used when you send no value. The key must be valid when `dcApiRequestType` is `signed`. |115| `dcApiRequestType` | `signed`, `unsigned` | Only with `dc_api` or `dc_api.jwt`. A missing value means `unsigned` for `dc_api` and `signed` for `dc_api.jwt`. Use `signed` in production. |116| `expectedOrigins` | array of strings | Mandatory when the effective `dcApiRequestType` is `signed`, and for `iso18013_7_annex_c`. The wallet ignores it for an unsigned request. |117| `encryptedResponseEncValuesSupported` | `A128CBC-HS256`, `A128GCM`, `A256GCM` | Mandatory for `direct_post.jwt`, and the verifier global configuration must permit encryption. An empty stored value falls back to all three. `dc_api.jwt` ignores this field and always uses `A256GCM`. |118| `directPostRedirectUri` | string | Only for `direct_post`. The server refuses it for `direct_post.jwt`, and it has no meaning for the DC API modes. |119| `scope` | string | For a scope-based presentation request. |120| `transactionDataDefinitionType` | `payment_data`, `payment`, `login_risk_transaction`, `login_risk_transaction_non_ts12`, `account_access`, `emandate`, `data_agreement_record`, `data_disclosure_agreement_record`, `qes_data` | Selects the JSON Schema that validates the `transactionData` of the verification request. Mandatory when the DCQL query asks for a Payment Wallet Attestation, a QESAC credential, or an SCA attestation. |121122### The DCQL query123`dcqlQuery` holds a mandatory `credentials` array with at least one entry, and an124optional top-level `credential_sets` array.125126Each entry of `dcqlQuery.credentials[]` needs `id` and `format`:127128- `id` - the identifier that `credential_sets` and the presentation response use.129 Use letters, digits, spaces, `_` and `-`. The server does not apply this check130 to the `iso18013_7_annex_c` version.131- `format` - `dc+sd-jwt`, `vc+sd-jwt`, `vp+sd-jwt`, `jwt_vc_json`, `jwt_vc` or132 `mso_mdoc`.133- `meta` - the format gates the keys. The server refuses a key that the format134 does not allow:135136 | `format` | Allowed `meta` keys |137 | --- | --- |138 | `mso_mdoc` | `doctype_value` only |139 | `dc+sd-jwt` | `vct_values` or `type_values` |140 | `jwt_vc_json` | `type_values` only; `vct_values` is refused |141 | `vc+sd-jwt`, `vp+sd-jwt`, `jwt_vc` | none - leave `meta` out |142143 `vct_values` is an array of accepted `vct` strings. `type_values` is an array144 of type sets: the credential must hold every type of at least one set.145 `doctype_value` is a single `docType` string, for example146 `org.iso.18013.5.1.mDL`.147- `claims` - the claims that you ask for. Leave it out to ask for the whole148 credential. Each item holds `id` (needed when you use `claim_sets`), `path`,149 and an optional `values` array that limits the accepted values. For150 `mso_mdoc`, `path` holds two elements: the namespace and the data element, for151 example `["org.iso.18013.5.1", "family_name"]`. For `jwt_vc_json`, `path`152 starts with `credentialSubject`.153- `claim_sets` - alternative sets of claim `id` values. The wallet satisfies the154 first set that it can. Send it only together with a non-empty `claims` array.155- `require_cryptographic_holder_binding` - `true` when the credential must prove156 that the holder owns it.157- `multiple` - `true` when the wallet can return more than one credential for158 this query.159- `trusted_authorities` - the issuers that you trust for this query. Each entry160 holds `type` (for example `etsi_tl` for an ETSI trusted list, or `aki` for an161 authority key identifier) and `values`.162163Each entry of `credential_sets[]` holds a mandatory `options` array with at least164one combination. Each combination is an array of credential query identifiers.165`required` says whether the wallet must satisfy one of the options, and `purpose`166gives the reason. `purpose` accepts a string, a number, or an object.167168```json169{170 "label": "Verify age over 18",171 "version": "version_01",172 "responseType": "vp_token",173 "responseMode": "direct_post",174 "dcqlQuery": {175 "credentials": [176 {177 "id": "age-attestation",178 "format": "mso_mdoc",179 "meta": { "doctype_value": "eu.europa.ec.av.1" },180 "claims": [181 { "path": ["eu.europa.ec.av.1", "age_over_18"] }182 ]183 }184 ]185 }186}187```188189### Send a verification request190`POST /v3/config/digital-wallet/openid/sdjwt/verification/send`191192`presentationDefinitionId` is the only mandatory field. The server reads the DCQL193query, the response mode, the transaction data template, and the DC API settings194from that record. A value shorter than three characters is ignored, and the195server then answers with HTTP 400, because no requirements are left.196197| Field | Note |198| --- | --- |199| `requestByReference` | Default `false`. `true` passes the Authorization Request with the `request_uri` parameter. Use it for a large request. |200| `transactionData` | Send it when, and only when, the presentation definition sets a `transactionDataDefinitionType`. The server answers HTTP 400 in both mismatched cases. The structure must follow the JSON Schema of that type. |201| `nonce` | The server makes one when you send no value. V3 only. |202| `urlPrefix` | Scheme prefix of the deep link in `vpTokenQrCode`. Default `openid4vp://`. V3 only. |203| `individualId` / `mapperId` | Send the request as a push notification to the device of that individual. Do not send both. V3 only. |204| `signatureStamp` / `signatureCoordinate` | Signed PDF options. `signatureCoordinate` holds exactly four integers, `[x1, y1, x2, y2]`, in points. V3 only. |205| `dataAgreement` | The terms of this verification exchange. V3 only. |206207The response holds `verificationHistory`. Fields to read:208209- `presentationExchangeId` - the correlation id. `id` holds the same value.210- `vpTokenQrCode` - the `openid4vp://` URI. Render it as a QR code or open it as211 a deep link.212- `status` - `request_sent`, `request_received`, `presentation_pending` or213 `presentation_acked`.214- `verified` - the boolean result.215- `presentation` - the disclosed claims, as an array.216- `vpTokenResponse` - an array. A non-empty value means that the holder answered.217- `presentationValidity` - the per-credential validity results.218- `responseMode`, which on a record can also hold `iar-post` or `iar-post.jwt`,219 and `responseType` (`vp_token`, `id_token`, `device_response`).220- `dcApiProtocol` - `openid4vp-v1-unsigned`, `openid4vp-v1-signed` or221 `org-iso-mdoc`, and `dcApiRequest`, which holds the ready-made222 `chrome.digital` and `safari.digital` request objects.223- `requestExpired`, `requestExpiryTime`, `nonce`, `requiresEncryption`,224 `idToken`, `idTokenDecoded`, `transactionData`, `transactionDataBase64`,225 `files` (each with `credentialId`, `signedFile`, `unsignedFile`, `error`,226 `errorDescription`).227228The read verification history operation returns the same record shape.229230### Receive a Digital Credentials API response231`POST /v2/config/digital-wallet/openid/sdjwt/verification/history/{presentationExchangeId}/receive`232233The body takes one of two shapes:234235- `{ "response": "<string>" }` - use it for `dc_api.jwt`, where the string is the236 JWE compact serialization (five base64url segments separated by `.`) that the237 wallet returned. Use it also for `dc_api` when the payload is a JSON-encoded238 string whose decoded form is `{"vp_token": { ... }}`.239- `{ "vp_token": { ... } }` - use it for `dc_api` when the browser returns the240 parsed JSON object. The object maps each DCQL credential query identifier to241 the Verifiable Presentation of the wallet. The encoding of each presentation242 follows the credential format.243244### Revalidate a verification245`POST /v2/config/digital-wallet/openid/sdjwt/verification/history/{presentationExchangeId}/revalidate`246has no request body; the server discards one if you send it. It checks the247credential signatures, the revocation status, and the trust chain again, writes248the new `presentationValidity` and `verified` values, and returns the full249record. Every other property stays the same.250251The path is `/v2`, but the response holds the **V3** record shape:252`vpTokenResponse` and `presentation` are arrays, and the V3-only properties are253present. This is the only V2 verification operation that answers with the V3254shape. The server does not compute `requestExpired` here; read the record with255the V3 read operation to get a current value.256257## Sandbox call style258Every Verifier operation except the list presentation definition templates259operation carries the optional `X-SandboxOrgId` header.260261- With a **bearer access token**, send `X-SandboxOrgId: <sandboxOrgId>`. The262 service then runs the call against the wallet of that sandbox organisation and263 not against the main wallet. Leave the header out to use the main wallet.264- With an **API key**, the header does nothing. The service takes the sandbox265 organisation from the key. Bind the key first with266 `PUT /v2/config/admin/apikey/{apiKeyId}/sandbox-org`.267- `X-SubwalletId` is the deprecated name of the header. The service still accepts268 it, and `X-SandboxOrgId` wins when you send both.269- The sandbox organisation must exist, must belong to your organisation, and must270 be deployed. Any other identifier fails with HTTP 400.271272Read `igrantio-api-sandboxes` for the sandbox organisation lifecycle.273274## Cross-references275- `igrantio-ows-overview` - architecture, glossary, and the shared contracts.276- `igrantio-api-holder` - the wallet that answers the Authorization Request.277- `igrantio-api-issuer` - the issuance side of the same organisation.278- `igrantio-api-key-management` - the verifier key that `kid` names, and the279 X.509 material for `x509_san_dns`, `x509_hash` and `iso18013_7_annex_c`.280- `igrantio-api-trust-anchor` - the trusted lists behind `trusted_authorities`.281- `igrantio-api-webhooks` - the presentation events that tell you when the282 holder answered.283- `igrantio-api-sandboxes` - the sandbox organisation lifecycle.284285## Documentation is the source of truth286This skill mirrors the iGrant.io OpenID4VC API documentation. If this skill and287the linked documentation disagree, **the documentation wins**. Before you rely288on a payload shape, fetch the linked page, or the raw specification at289<https://docs.igrant.io/openapispecifications/oid4vc.yaml>, and check for290updates. Follow the documentation and report the drift so this skill can be291corrected.292293- Verifier API index: <https://docs.igrant.io/docs/developer-apis/>294- Workflow, send and verify credentials (OID4VP): <https://docs.igrant.io/docs/openID4vc-send-verify-credentials/>295- DCQL patterns: the `igrantio-dcql-*` workflow skills.