API Reference
Complete endpoint reference for the Verification API
POST /verifier/request
Create an OID4VP authorization request.
Authentication: API key (publishable or secret)
Request body
{
"version": "v1",
"dcql_query": {
"credentials": [{
"id": "pid",
"format": "mso_mdoc",
"meta": { "doctype_value": "eu.europa.ec.eudi.pid.1" },
"claims": [
{ "path": ["eu.europa.ec.eudi.pid.1", "given_name"] }
]
}]
}
}| Field | Type | Required | Description |
|---|---|---|---|
version | "v1" | "draft18" | No | Protocol version. Default: "v1" |
namespace | string | No | mDoc namespace for simple queries (auto-generates DCQL) |
attributes | string[] | No | Attribute names within the namespace |
claims | array | No | Per-attribute namespace claims: { namespace, id, intent_to_retain }. Alternative to attributes for credentials whose attributes span multiple namespaces |
scheme | "openid4vp" | "mdoc-openid4vp" | "haip-vp" | "av" | No | URL scheme for the request URI. "av" is the only way to trigger the AV profile |
haip | boolean | No | Use the HAIP profile (x509_hash client_id, haip-vp:// scheme). Default: true for v1. Set false for plain OID4VP v1 with x509_san_dns and openid4vp:// |
callback | boolean | No | Include a redirect_uri in the authorization response (same-device flows) |
dcql_query | DcqlQuery | No | Full DCQL query (v1 only) |
presentation_definition | PresentationDefinition | No | PEX query (draft18 only) |
Provide either namespace + attributes for a simple query, or dcql_query / presentation_definition for full control.
Response 200
{
"url": "haip-vp://?client_id=x509_hash%3A...&request_uri=https%3A%2F%2Fapi.verifiables.com%2Fverifier%2Fauthorization%2Frequest.jwt%2F550e8400-e29b-41d4-a716-446655440000&request_uri_method=post",
"id": "550e8400-e29b-41d4-a716-446655440000",
"version": "v1"
}The default v1 request uses the haip-vp:// scheme (haip defaults to true). Pass haip: false to get an openid4vp:// request, or set scheme explicitly.
| Field | Type | Description |
|---|---|---|
url | string | Authorization request URI, display as QR code or deep link |
id | string (UUID) | Request ID for polling status |
version | string | Protocol version used |
POST /verifier/validate
Parse and resolve an existing OID4VP authorization request. This is a wallet-side helper: given an authorization request URI (or JWT), it parses the request and resolves it so a wallet can understand which credentials are being requested.
Authentication: API key (publishable or secret)
Request body
{
"authorizationRequest": "haip-vp://?client_id=x509_hash%3A...&request_uri=..."
}| Field | Type | Required | Description |
|---|---|---|---|
authorizationRequest | string | Yes | The authorization request to resolve (request URI or raw request string) |
Response 200
Returns the resolved authorization request: the parsed payload (client_id, nonce, response_uri, DCQL query or presentation definition) as produced by resolving the request for a direct_post response.
GET /verifier/status/:request_id
Poll for the verification result after creating a request.
Authentication: API key (publishable or secret)
Path parameters
| Parameter | Type | Description |
|---|---|---|
request_id | string (UUID) | The id returned by POST /verifier/request |
Response 200: Verified
{
"status": "valid",
"verification": {
"ISSUER_AUTH": [
{ "status": "✅", "check": "Issuer certificate must be valid" },
{ "status": "✅", "check": "The MSO must be valid at the time of verification" }
],
"DEVICE_AUTH": [
{ "status": "✅", "check": "Device signature must be valid" }
]
},
"presentation": {
"eu.europa.ec.eudi.pid.1": {
"given_name": "Marie",
"family_name": "Dupont",
"birth_date": "1990-01-15"
}
}
}| Field | Type | Description |
|---|---|---|
status | "created" | "claimed" | "valid" | "failed" | Current request state |
verification | object | Verification checks grouped by category. Check status is "✅" (passed) or "🛑" (failed) |
presentation | object | Extracted claims keyed by namespace/doctype (mDoc) or vct (SD-JWT) |
Status lifecycle
| Status | Meaning |
|---|---|
created | Request created, waiting for wallet to fetch it |
claimed | Wallet fetched the request JWT |
valid | Credential verified successfully |
failed | Cryptographic verification failed |
Requests expire after 600 seconds. Once the wallet response has been processed (valid or failed), the result is kept for 60 seconds. After expiry the endpoint returns the "Not found" response below. If the status is created or claimed, poll again after 2 seconds.
Response 200: Not found
{
"error": "Authorization status not found"
}POST /verifier/response
Submit a verification response server-side. Used for server-to-server verification flows where you handle the wallet interaction yourself.
Authentication: API key (publishable or secret)
Request body
{
"request": {},
"response": {},
"jwe": "eyJ..."
}| Field | Type | Required | Description |
|---|---|---|---|
request | object | Yes | Original authorization request payload |
response | object | Yes | Authorization response payload |
jwe | string | Yes | Encrypted JARM response (JWE) |
Schema objects
DcqlQuery object
{
"credentials": [
{
"id": "pid",
"format": "mso_mdoc",
"meta": { "doctype_value": "eu.europa.ec.eudi.pid.1" },
"claims": [
{
"path": ["eu.europa.ec.eudi.pid.1", "given_name"],
"intent_to_retain": false
}
],
"trusted_authorities": [
{ "type": "aki", "values": ["MIGf..."] }
]
}
],
"credential_sets": [
{ "options": [["pid"]], "required": true }
]
}credentials[]
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Unique credential identifier within the query |
format | "mso_mdoc" | "dc+sd-jwt" | "vc+sd-jwt" | Yes | Credential format |
meta.doctype_value | string | No | mDoc doctype (required for mso_mdoc) |
meta.vct_values | string[] | No | SD-JWT verifiable credential types |
claims | array | No | Requested claims (see below) |
require_cryptographic_holder_binding | boolean | No | Require device binding |
multiple | boolean | No | Accept multiple credentials |
trusted_authorities | array | No | Trusted issuers (see Trusted Authorities) |
claims[]
| Field | Type | Required | Description |
|---|---|---|---|
path | string[] | Yes | Claim path: [namespace, attribute] for mDoc, [attribute] for SD-JWT |
id | string | No | Claim identifier |
intent_to_retain | boolean | No | Declare intent to store the value |
values | array | No | Acceptable values constraint |
credential_sets[]
| Field | Type | Required | Description |
|---|---|---|---|
options | string[][] | Yes | Groups of credential ids (one group must be satisfied) |
required | boolean | No | Whether this set is mandatory |
PresentationDefinition object
Used with version: "draft18" only.
{
"id": "example",
"input_descriptors": [{
"id": "pid",
"format": {
"mso_mdoc": { "alg": ["ES256"] }
},
"constraints": {
"fields": [
{ "path": ["$['eu.europa.ec.eudi.pid.1']['given_name']"] }
],
"limit_disclosure": "required"
}
}]
}input_descriptors[]
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Descriptor identifier |
format | object | Yes | Accepted formats with algorithms |
constraints.fields | array | Yes | Required fields with JSON path |
constraints.limit_disclosure | string | No | "required" to minimize disclosure |
Protocol endpoints
These endpoints are called by wallets directly. You do not need to call them.
| Method | Path | Description |
|---|---|---|
GET | /verifier/authorization/request.jwt/:request_id | Wallet fetches the signed request JWT |
POST | /verifier/authorization/request.jwt/:request_id | POST variant: wallet supplies wallet_nonce / wallet_metadata, the JAR is re-signed with the nonce included |
POST | /verifier/authorization/response.jwt/:request_id | Wallet submits the encrypted (JARM) response |
POST | /verifier/authorization/response/:request_id | Wallet submits a plain (non-JWE) response. Used by the AV profile |
GET/POST | /verifier/callback | Same-device redirect callback |