Response Handling
Process and validate wallet responses to verification requests
After a wallet submits its credential presentation, the API decrypts, verifies, and stores the result. You retrieve it by polling the status endpoint.
Polling for results
GET /verifier/status/:request_id
Authorization: Bearer oat_your_publishable_keyPoll this endpoint while the status is created (wallet has not fetched the request yet) or claimed (wallet fetched the request JWT but has not responded):
async function waitForResult(requestId, apiKey) {
while (true) {
const res = await fetch(`${BASE_URL}/verifier/status/${requestId}`, {
headers: { Authorization: `Bearer ${apiKey}` },
})
const data = await res.json()
if (data.status !== 'created' && data.status !== 'claimed') return data
await new Promise((r) => setTimeout(r, 2000))
}
}Response format
The result has three top-level fields: status (valid or failed), verification (arrays of cryptographic checks grouped by check category, each with an emoji status: ✅ passed, 🛑 failed), and presentation (extracted claims keyed by namespace/doctype for mDoc, or by vct for SD-JWT).
mDoc response
{
"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" }
],
"DATA_INTEGRITY": [
{ "status": "✅", "check": "Issuer Auth must include a supported digestAlgorithm element" }
],
"query_validation": [
{ "status": "✅", "check": "Presentation satisfies query: pid" }
]
},
"presentation": {
"eu.europa.ec.eudi.pid.1": {
"family_name": "Dupont",
"given_name": "Marie",
"birth_date": "1990-01-15",
"age_over_18": true
}
}
}SD-JWT response
{
"status": "valid",
"verification": {
"issuer_auth": [
{ "status": "✅", "check": "SD-JWT issuer signature verified" }
],
"holder_binding": [
{ "status": "✅", "check": "KB-JWT signature and claims verified" }
]
},
"presentation": {
"eu.europa.ec.eudi.pid.1": {
"family_name": "Dupont",
"given_name": "Marie"
}
}
}What gets verified
The API performs full cryptographic verification before returning a valid status:
mDoc verification
- Device signature validation (ECDSA)
- Issuer-signed data integrity (MSO digest matching)
- Certificate chain validation
- Session transcript binding (OID4VP Annex B.3.4.1)
SD-JWT verification
- Issuer signature validation (ES256)
- Key binding JWT validation (nonce + audience)
- Disclosure hash verification
- Expiration and issuance date checks
Error states
When verification fails, the status is failed and the failing checks appear inside verification with a 🛑 status. Failed checks may carry an additional reason field explaining why:
{
"status": "failed",
"verification": {
"DEVICE_AUTH": [
{
"status": "🛑",
"check": "Device signature must be valid",
"reason": "Signature verification failed"
}
]
},
"presentation": {}
}There is no top-level error field. If the request record has expired (600 seconds without a response, or 60 seconds after the result was stored), the status endpoint returns:
{
"error": "Authorization status not found"
}