Send verification request
POST/v3/config/digital-wallet/openid/sdjwt/verification/send
Sends an OpenID4VP Authorization Request from a stored presentation definition. Set presentationDefinitionId: the server reads the DCQL query, the response mode, the transaction data template and the DC API settings from that record.
The response mode of the presentation definition sets the transport:
direct_post/direct_post.jwt: the response holdsvpTokenQrCodeandvpTokenRequest. ShowvpTokenQrCodeas a QR code, or open it as a deep link. The wallet posts the response to the response URI of the verifier.dc_api/dc_api.jwt: the response holdsdcApiRequest(one shape for Chrome and one for Safari) anddcApiProtocol. The verifier frontend givesdcApiRequest.chrome(ordcApiRequest.safari) tonavigator.credentials.get()and forwards the answer of the wallet toPOST /v2/config/digital-wallet/openid/sdjwt/verification/history/{presentationExchangeId}/receive.vpTokenQrCodeandvpTokenRequestare empty.
Send transactionData when, and only when, the presentation definition sets a transactionDataDefinitionType.
Set individualId or mapperId to push the Authorization Request to the device of a known individual. The individual must have a push notification token. Do not set both properties in one request.
Read presentationExchangeId from the response. Every other verification operation takes that value as its path parameter. id holds the same value.
The request lifetime is presentationRequestExpiresIn of the verifier global configuration, counted from createdAt.
Request
- application/json
Body
required
Delivery options for the Authorization Request. Set presentationDefinitionId to name the stored presentation definition that holds the credential requirements.
Identifier of a stored presentation definition. The server reads the DCQL query, the response mode, the transaction data template and the DC API settings from this record. A value shorter than three characters, or an unknown identifier, gives HTTP 400.
Default value: false
When true, the server passes the Authorization Request by reference with the request_uri parameter. The wallet then gets the full request from that URI. Use this option for large Authorization Requests.
transactionData object
Transaction data to add to the Authorization Request. The holder must approve this data before the wallet sends the presentation.
Give this property when, and only when, the presentation definition that presentationDefinitionId names sets a transaction data template type. The server answers with HTTP 400 when the definition sets a template type and the body has no transactionData, and also when the definition sets no template type and the body has transactionData.
The structure must agree with the JSON Schema of the template type of the presentation definition.
Transaction data to add to the Authorization Request. The holder must approve this data before the wallet sends the presentation.
Give this property when, and only when, the presentation definition that presentationDefinitionId names sets a transaction data template type. The server answers with HTTP 400 when the definition sets a template type and the body has no transactionData, and also when the definition sets no template type and the body has transactionData.
The structure must agree with the JSON Schema of the template type of the presentation definition.
Cryptographic nonce for the Authorization Request. The server makes a nonce if you do not supply one.
URL scheme prefix for the Authorization Request deep link that the server returns in vpTokenQrCode. The default is openid4vp://. Use a different prefix to open a specific wallet.
Identifier of an individual in the organisation. The server sends a push notification with the Authorization Request to the device of this individual. The individual must have a push notification token. Do not set individualId and mapperId together.
External identifier that maps to an individual in the organisation. The server sends a push notification with the Authorization Request to the device of that individual. The individual must have a push notification token. Do not set individualId and mapperId together.
Default value: false
When true, the server puts a visible signature stamp in the signed PDF that the flow makes.
Possible values: >= 4, <= 4
Page coordinates of the signature in the signed PDF, as [x1, y1, x2, y2] in points. The array must hold exactly four integers.
dataAgreement object
Data agreement that gives the terms for this verification exchange.
Data agreement that gives the terms for this verification exchange.
Responses
- 200
- 400
- 401
- 500
The server made the Authorization Request and saved the verification exchange record.
Response Headers
- application/json
- Schema
- Example (from schema)
- Direct Post (direct_post)
- DC API Unsigned (dc_api)
- DC API Signed + Encrypted (dc_api.jwt)
Schema
- Array [
- ]
request_sent: The server made the OpenID4VP Authorization Request. The exchange waits for the holder.request_received: The wallet of the holder got, or scanned, the Authorization Request.presentation_pending: The wallet started the response but the verifier did not get a complete Authorization Response yet.presentation_acked: The holder sent the Verifiable Presentation and the verifier processed it.direct_post: Response sent via HTTP POST to the verifier'sredirect_uriwithout encryption.direct_post.jwt: Response sent via HTTP POST encrypted as a JWE.dc_api: Response delivered over the W3C Digital Credentials API transport without JWE encryption. Compatible with bothsignedandunsigneddcApiRequestTypevalues.dc_api.jwt: Response delivered over the W3C Digital Credentials API transport encrypted as a JWE.iar-post: Response sent through the Interactive Authorisation Request transport without encryption.iar-post.jwt: Response sent through the Interactive Authorisation Request transport encrypted as a JWE.openid4vp-v1-unsigned: The Authorization Request goes to the DC API of the browser without a signature. The browser can inspect the request for risk analysis. Use it for development and tests only.openid4vp-v1-signed: The verifier key signs the Authorization Request, and the request goes to the DC API of the browser as an opaque string. This gives verifier authentication. Use it for live use.org-iso-mdoc: The Authorization Request follows ISO 18013-7 Annex C. The wallet answers with an encrypted CBOREncryptedResponse. Only present for the DC API response modes and foriso18013_7_annex_c.- Array [
- For
openid4vp-v1-signed: Contains{ "request": "<signed-JWT>" }, a JWT signed by the verifier's key. - For
openid4vp-v1-unsigned: Contains the full Authorization Request object withclient_metadata,dcql_query,nonce,response_mode,response_type. - For
openid4vp-v1-signed: Contains{ "request": "<signed-JWT>" }, a JWT signed by the verifier's key. - For
openid4vp-v1-unsigned: Contains the full Authorization Request object withclient_metadata,dcql_query,nonce,response_mode,response_type. - ]
- Array [
- For
openid4vp-v1-signed:{ "request": "<signed-JWT>" }. - For
openid4vp-v1-unsigned: the full inline Authorization Request object (response_type,response_mode,nonce,dcql_query,client_metadata, …). - ]
- Array [
- ]
verificationHistory objectrequired
Verification exchange record. The record tracks one OpenID for Verifiable Presentation (OpenID4VP) verification, from the Authorization Request to the verification result.
The server returns every property of this schema on every operation, except dcApiRequest, dcApiProtocol, cryptographicKeyFormat, cryptographicKeyIdentifier and presentationDefinitionSnapshot, which it leaves out when they hold no value. A property that has no value yet holds the empty value for its type: "" for a string, 0 for a number, false for a boolean and null for an object or an array.
The record has no expiry flag. The request lifetime is presentationRequestExpiresIn of the verifier global configuration, counted from createdAt.
Unique identifier of the verification exchange. Give this value as the presentationExchangeId path parameter to read, delete or revalidate the record, and to receive a DC API response for it.
Identifier of the record. It holds the same value as presentationExchangeId.
OpenID4VP Authorization Request URI encoded for QR code display or deep link. The holder's wallet scans or clicks this to initiate the presentation flow. Empty when using DC API response modes (dc_api or dc_api.jwt).
State parameter for the OpenID4VP Authorization Request, used to correlate the request with the response.
Full OpenID4VP Authorization Request URI or payload. Empty when using DC API response modes (dc_api or dc_api.jwt).
presentationSubmission objectrequired
Wrapper that holds the Presentation Submission object of the wallet.
DCQL is the only supported query form, and a DCQL Authorization Response carries no Presentation Submission, so the server returns null here for every verification that a current presentation definition starts. A value is present only on an old record that a DIF Presentation Exchange definition made. Read presentation to get the credentials of the holder.
presentation_submission object
DIF Presentation Exchange Submission object that maps the credentials of the holder to the requirements of the verifier. Kept for old records only.
Identifier of the Presentation Definition that this submission fulfills.
descriptor_map object[]required
Array of Descriptor Map entries mapping each requested credential to its location in the Verifiable Presentation.
Credential format of the matched credential (e.g. jwt_vc_json, dc+sd-jwt, mso_mdoc).
Identifier of the Input Descriptor from the Presentation Definition that this entry satisfies.
JSONPath expression pointing to the Verifiable Credential within the Verifiable Presentation token.
path_nested object
Nested path descriptor for credentials wrapped in envelope formats (e.g. JWT inside a VP JWT).
Credential format of the nested credential (e.g. jwt_vc_json, dc+sd-jwt, mso_mdoc).
Identifier of the Input Descriptor from the Presentation Definition that this nested entry satisfies.
JSONPath expression pointing to the credential within the nested envelope.
Unique identifier for this Presentation Submission.
Possible values: [request_sent, request_received, presentation_pending, presentation_acked]
Lifecycle status of the verification exchange:
Result of the verification of the Verifiable Presentation. The server checks the cryptographic signatures, the credential status and the presented claims against the DCQL query of the presentation definition.
Unix timestamp (in seconds) when this verification record was created.
Unix timestamp (in seconds) when this verification record was last modified.
Identifier of the presentation definition used for this verification request.
Identifier of the digital wallet of the organisation that sent this verification request.
holder objectrequired
Metadata of the holder.
Identifier of the holder, for example a DID or the name from the client metadata. An empty string when the server has no value.
Decoded credentials that the holder presented. The shape of each entry follows the credential format. null until the holder answers.
Verifiable Presentation tokens that the wallet sent. The array holds one entry for each credential that the Authorization Request asked for. null until the wallet answers.
transactionData objectrequired
Transaction data confirmed by the holder during the presentation flow.
Transaction data confirmed by the holder during the presentation flow.
Base64url encoding of the transaction data that the Authorization Request holds.
Identifier of the credential issuance exchange that this verification started, if the flow issues a credential after the verification. Always empty on the response of the send operation. The server fills it in later, when the issuance flow starts.
Possible values: [vp_token, device_response]
OAuth 2.0 response type of the Authorization Request.
Identifier of the data agreement record that this verification exchange created.
Identifier of the dashboard user or individual that started this verification request.
Validation result for each credential in the presentation, with the signature check, the expiry check and the revocation status. The revalidate operation writes a new value here. null until the holder answers.
Possible values: [redirect_uri, did, verifier_attestation, x509_san_dns, x509_hash]
Client ID scheme used by the verifier in the OpenID4VP Authorization Request.
URI that the wallet opens after it posts the Authorization Response. Empty for the DC API response modes (dc_api or dc_api.jwt).
Possible values: [direct_post, direct_post.jwt, dc_api, dc_api.jwt, iar-post, iar-post.jwt]
OpenID4VP response mode determining how the Authorization Response is delivered:
Verifier Attestation JWT sent to the holder, proving the verifier's authorization.
Identifier of the individual that the server sent the Authorization Request to with a push notification. Empty when the send request did not set individualId.
External identifier of the individual that the server sent the Authorization Request to with a push notification. Empty when the send request did not set mapperId.
dataAgreement objectrequired
Data agreement that gives the terms for this verification exchange.
Data agreement that gives the terms for this verification exchange.
Cryptographic nonce used in the OpenID4VP Authorization Request to ensure freshness and prevent replay attacks.
Possible values: [openid4vp-v1-unsigned, openid4vp-v1-signed, org-iso-mdoc]
Digital Credentials API exchange protocol identifier returned when the presentation definition is configured for DC API response modes.
Identifies the protocol variant used with the W3C Digital Credentials API (navigator.credentials.get()):
dcApiRequest object
Request object for the W3C Digital Credentials API, structured for browser invocation via navigator.credentials.get().
Contains browser-specific request formats for Chrome and Safari.
Only present when responseMode is dc_api or dc_api.jwt.
chrome object
Digital Credentials API request format for Chromium-based browsers. Uses the providers structure per the W3C Digital Credentials API specification.
digital object
Digital credential request options for Chromium-based browsers.
providers object[]
Array of credential request providers, each specifying a protocol and request data.
Digital Credentials API exchange protocol identifier (e.g. openid4vp-v1-signed, openid4vp-v1-unsigned).
request object
The OpenID4VP Authorization Request payload. Structure varies by protocol:
The OpenID4VP Authorization Request payload. Structure varies by protocol:
safari object
Digital Credentials API request format for Safari-based browsers. Uses the requests structure.
digital object
Digital credential request options for Safari-based browsers.
requests object[]
Array of credential requests for Safari, each containing data and protocol.
JSON-stringified Authorization Request payload (Safari's DC API expects a string, not an object).
Decoding it yields the same structure that Chrome receives in request:
Digital Credentials API exchange protocol identifier (e.g. openid4vp-v1-signed, openid4vp-v1-unsigned).
true when the wallet must encrypt the Authorization Response as a JWE: for the direct_post.jwt and dc_api.jwt response modes, and for iso18013_7_annex_c. false for direct_post and dc_api.
When false, the signature stamp is hidden in signed PDFs.
Possible values: >= 4, <= 4
Page coordinates of the signature in the signed PDF, as [x1, y1, x2, y2] in points.
files object[]required
List of files generated during the verification, including signed and unsigned PDF documents.
Identifier of the credential associated with this file.
Error code if signing failed, null otherwise.
Detailed error message if signing failed, null otherwise.
URL of the signed PDF file.
URL of the unsigned PDF file.
Key identifier of the key that signed the Authorization Request. The server leaves this property out when the request is not signed.
Possible values: [did:key, x509]
Format of the key that signed the Authorization Request. The server leaves this property out when the request is not signed.
presentationDefinitionSnapshot object
Copy of the presentation definition at the time of the request, in the shape of the presentation definition record. A later change of the presentation definition does not change a request that is already out.
Copy of the presentation definition at the time of the request, in the shape of the presentation definition record. A later change of the presentation definition does not change a request that is already out.
{
"verificationHistory": {
"presentationExchangeId": "8e9c0a94-3b7d-4f2c-9d11-2f5a0b1c8d3e",
"id": "8e9c0a94-3b7d-4f2c-9d11-2f5a0b1c8d3e",
"vpTokenQrCode": "string",
"vpTokenRequestState": "string",
"vpTokenRequest": "string",
"presentationSubmission": {
"presentation_submission": {
"definition_id": "string",
"descriptor_map": [
{
"format": "string",
"id": "string",
"path": "string",
"path_nested": {
"format": "string",
"id": "string",
"path": "string"
}
}
],
"id": "string"
}
},
"status": "request_sent",
"verified": true,
"createdAt": 0,
"updatedAt": 0,
"presentationDefinitionId": "string",
"openIdOrganisationId": "string",
"holder": {
"name": "string"
},
"presentation": [
{}
],
"vpTokenResponse": [
"string"
],
"transactionData": {},
"transactionDataBase64": "string",
"credentialExchangeId": "string",
"responseType": "vp_token",
"dataAgreementId": "string",
"userId": "string",
"presentationValidity": [
{}
],
"clientIdScheme": "redirect_uri",
"directPostRedirectUri": "string",
"responseMode": "direct_post",
"verifierAttestation": "string",
"individualId": "string",
"mapperId": "string",
"dataAgreement": {},
"nonce": "string",
"dcApiProtocol": "openid4vp-v1-unsigned",
"dcApiRequest": {
"chrome": {
"digital": {
"providers": [
{
"protocol": "string",
"request": {}
}
]
}
},
"safari": {
"digital": {
"requests": [
{
"data": "string",
"protocol": "string"
}
]
}
}
},
"requiresEncryption": true,
"signatureStamp": true,
"signatureCoordinate": [
100,
100,
200,
150
],
"files": [
{
"credentialId": "string",
"error": "string",
"errorDescription": "string",
"signedFile": "string",
"unsignedFile": "string"
}
],
"cryptographicKeyIdentifier": "string",
"cryptographicKeyFormat": "did:key",
"presentationDefinitionSnapshot": {}
}
}
Holder scans vpTokenQrCode or follows the deep link
{
"verificationHistory": {
"id": "8e9c0a94-3b7d-4f2c-9d11-2f5a0b1c8d3e",
"presentationExchangeId": "8e9c0a94-3b7d-4f2c-9d11-2f5a0b1c8d3e",
"presentationDefinitionId": "1c3f6b1c-0c48-4b1f-9c1a-77f9c1d6a1a0",
"vpTokenQrCode": "openid4vp://?client_id=x509_hash%3AUvRWgUwGzT3x1qSWmE1Rhj3u2QkAvWkDTz5FZ6a3fY8&request_uri=https%3A%2F%2Fdemo-api.igrant.io%2Forganisation%2Fxyz%2Fservice%2Fverification%2F8e9c0a94-3b7d-4f2c-9d11-2f5a0b1c8d3e&request_uri_method=post",
"vpTokenRequest": "eyJhbGciOiJFUzI1NiIsInR5cCI6Im9hdXRoLWF1dGh6LXJlcStqd3QiLCJ4NWMiOlsiTUlJQi4uLiJdfQ.eyJjbGllbnRfaWQiOiJ4NTA5X2hhc2g6Li4uIn0.signature",
"vpTokenRequestState": "5d8f2c9b-c2a4-4f0c-9a7d-1c2b3a4d5e6f",
"responseMode": "direct_post",
"clientIdScheme": "x509_hash",
"requiresEncryption": false,
"nonce": "z4cVLRsq9pKx0NgQ7E3hJg",
"openIdOrganisationId": "7f9b1e2c-3a4d-4b5e-8c9f-0a1b2c3d4e5f",
"status": "request_sent",
"verified": false,
"holder": {
"name": ""
},
"responseType": "vp_token",
"verifierAttestation": "",
"directPostRedirectUri": "",
"credentialExchangeId": "",
"transactionDataBase64": "",
"dataAgreementId": "",
"userId": "",
"individualId": "",
"mapperId": "",
"signatureStamp": false,
"cryptographicKeyFormat": "x509",
"createdAt": 1747011600,
"updatedAt": 1747011600
}
}
Verifier frontend invokes navigator.credentials.get() with dcApiRequest
{
"verificationHistory": {
"id": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"presentationExchangeId": "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"presentationDefinitionId": "1c3f6b1c-0c48-4b1f-9c1a-77f9c1d6a1a0",
"vpTokenQrCode": "",
"vpTokenRequest": "",
"vpTokenRequestState": "f3e2d1c0-b9a8-7654-3210-fedcba987654",
"responseMode": "dc_api",
"clientIdScheme": "x509_hash",
"requiresEncryption": false,
"nonce": "z4cVLRsq9pKx0NgQ7E3hJg",
"dcApiProtocol": "openid4vp-v1-unsigned",
"dcApiRequest": {
"chrome": {
"digital": {
"providers": [
{
"protocol": "openid4vp-v1-unsigned",
"request": {
"response_type": "vp_token",
"response_mode": "dc_api",
"nonce": "z4cVLRsq9pKx0NgQ7E3hJg",
"dcql_query": {
"credentials": [
{
"id": "Person-Identification-Data-PID",
"format": "dc+sd-jwt",
"meta": {
"vct_values": [
"PersonIdentificationData"
]
},
"claims": [
{
"path": [
"family_name"
]
},
{
"path": [
"given_name"
]
}
]
}
]
},
"client_metadata": {
"client_name": "Example Verifier",
"vp_formats_supported": {
"dc+sd-jwt": {
"sd-jwt_alg_values": [
"ES256"
],
"kb-jwt_alg_values": [
"ES256"
]
}
}
}
}
}
]
}
},
"safari": {
"digital": {
"requests": [
{
"protocol": "openid4vp-v1-unsigned",
"data": "{\"response_type\":\"vp_token\",\"response_mode\":\"dc_api\",\"nonce\":\"z4cVLRsq9pKx0NgQ7E3hJg\",\"dcql_query\":{\"credentials\":[{\"id\":\"Person-Identification-Data-PID\",\"format\":\"dc+sd-jwt\",\"meta\":{\"vct_values\":[\"PersonIdentificationData\"]},\"claims\":[{\"path\":[\"family_name\"]},{\"path\":[\"given_name\"]}]}]},\"client_metadata\":{\"client_name\":\"Example Verifier\"}}"
}
]
}
}
},
"openIdOrganisationId": "7f9b1e2c-3a4d-4b5e-8c9f-0a1b2c3d4e5f",
"status": "request_sent",
"verified": false,
"holder": {
"name": ""
},
"responseType": "vp_token",
"verifierAttestation": "",
"directPostRedirectUri": "",
"credentialExchangeId": "",
"transactionDataBase64": "",
"dataAgreementId": "",
"userId": "",
"individualId": "",
"mapperId": "",
"signatureStamp": false,
"cryptographicKeyFormat": "x509",
"createdAt": 1747011600,
"updatedAt": 1747011600
}
}
Signed Authorization Request JWT, wallet response will be returned as a JWE
{
"verificationHistory": {
"id": "9f8e7d6c-5b4a-3210-fedc-ba9876543210",
"presentationExchangeId": "9f8e7d6c-5b4a-3210-fedc-ba9876543210",
"presentationDefinitionId": "1c3f6b1c-0c48-4b1f-9c1a-77f9c1d6a1a0",
"vpTokenQrCode": "",
"vpTokenRequest": "",
"vpTokenRequestState": "11111111-2222-3333-4444-555555555555",
"responseMode": "dc_api.jwt",
"clientIdScheme": "x509_hash",
"requiresEncryption": true,
"nonce": "uVj0pAq4cZmDk2yL6RxBvg",
"dcApiProtocol": "openid4vp-v1-signed",
"dcApiRequest": {
"chrome": {
"digital": {
"providers": [
{
"protocol": "openid4vp-v1-signed",
"request": {
"request": "eyJhbGciOiJFUzI1NiIsInR5cCI6Im9hdXRoLWF1dGh6LXJlcStqd3QiLCJ4NWMiOlsiTUlJQi4uLiJdfQ.eyJjbGllbnRfaWQiOiJ4NTA5X2hhc2g6VXZSV2dVd0d6VDN4MXFTV21FMVJoajN1MlFrQXZXa0RUejVGWjZhM2ZZOCIsInJlc3BvbnNlX3R5cGUiOiJ2cF90b2tlbiIsInJlc3BvbnNlX21vZGUiOiJkY19hcGkuand0IiwiZXhwZWN0ZWRfb3JpZ2lucyI6WyJodHRwczovL3ZlcmlmaWVyLmV4YW1wbGUuY29tIl0sImRjcWxfcXVlcnkiOnsiY3JlZGVudGlhbHMiOlsiLi4uIl19fQ.signature"
}
}
]
}
},
"safari": {
"digital": {
"requests": [
{
"protocol": "openid4vp-v1-signed",
"data": "{\"request\":\"eyJhbGciOiJFUzI1NiIsInR5cCI6Im9hdXRoLWF1dGh6LXJlcStqd3QiLCJ4NWMiOlsiTUlJQi4uLiJdfQ.eyJjbGllbnRfaWQiOiJ4NTA5X2hhc2g6Li4uIn0.signature\"}"
}
]
}
}
},
"openIdOrganisationId": "7f9b1e2c-3a4d-4b5e-8c9f-0a1b2c3d4e5f",
"status": "request_sent",
"verified": false,
"holder": {
"name": ""
},
"responseType": "vp_token",
"verifierAttestation": "",
"directPostRedirectUri": "",
"credentialExchangeId": "",
"transactionDataBase64": "",
"dataAgreementId": "",
"userId": "",
"individualId": "",
"mapperId": "",
"signatureStamp": false,
"cryptographicKeyFormat": "x509",
"createdAt": 1747011600,
"updatedAt": 1747011600
}
}
The body has no presentationDefinitionId, no presentation definition has that identifier, transactionData is missing for a presentation definition with a transaction data template (or is sent for one without), transactionData does not follow the JSON Schema of the template, a field has the wrong JSON type, or the organisation has no deployed digital wallet.
Response Headers
- application/json
- Schema
- Example (from schema)
Schema
{
"errorCode": 400,
"errorDescription": "Bad input parameter"
}
Unauthorized
Response Headers
- application/json
- Schema
- Example (from schema)
Schema
{
"errorCode": 400,
"errorDescription": "Bad input parameter"
}
Internal server error. The server also answers with this status when the body sets individualId and mapperId together, when the individual is unknown, or when the individual has no push notification token.
Response Headers
- application/json
- Schema
- Example (from schema)
Schema
{
"errorCode": 400,
"errorDescription": "Bad input parameter"
}