Verifying proofs from vouch
Under Development: This API is currently in development. Documentation and endpoints may change. For production use, please contact our team.
When using the vouch platform to generate web proofs, you’ll receive webhook responses that include both the proof and the associated data.
This guide shows you how to extract and verify these proofs using the POST /api/v2.0/verify endpoint.
Webhook Response Structure
When a user completes verification through vouch, a webhook is sent to your configured webhookUrl containing:
requestId: Unique identifier for the verification requestdataSourceId: Identifier for the data source used in this verificationoutputs: Aggregated extracted data from all web proofswebProofs: Array of web proof objects, each containing:outputs: Data extracted from this specific proofpresentationJson: The presentation object (for verification)decodedTranscript: Human-readable HTTP request/response data
To receive webhook responses, you need to configure a webhookUrl when initiating the verification flow. See the Vouch Getting Started guide or Vouch Integration Example for details on setting up webhooks.
Extracting and Verifying a Web Proof
Step 1: Extract the presentation from webhook response
The presentationJson field contains the cryptographic proof that can be verified independently:
// Example webhook payload received at your endpoint
const webhookPayload = {
requestId: "00000000-0000-0000-0000-000000000000",
dataSourceId: "00000000-0000-0000-0000-000000000000",
outputs: {
"Country": "en-US",
"Full Name": "Jane Doe"
},
webProofs: [
{
outputs: {
"Country": "en-US",
"Full Name": "Jane Doe"
},
decodedTranscript: { /* ... */ },
presentationJson: {
data: "014000000000000000af5e...",
meta: {
notaryUrl: "https://notary.production.vlayer.xyz/v2.0.0",
websocketProxyUrl: "ws://proxy.vlayer.xyz:80"
},
version: "2.0.0"
}
}
]
};
// Extract first proof - production apps should make sure to verify all delivered proofs
const presentation = webhookPayload.webProofs?.[0]?.presentationJson;
if (!presentation) throw new Error("No webProofs or presentationJson found");# Example webhook payload received at your endpoint
WEBHOOK_PAYLOAD='{
"requestId": "00000000-0000-0000-0000-000000000000",
"dataSourceId": "00000000-0000-0000-0000-000000000000",
"outputs": {
"Country": "en-US",
"Full Name": "Jane Doe"
},
"webProofs": [
{
"outputs": {
"Country": "en-US",
"Full Name": "Jane Doe"
},
"decodedTranscript": { "..." },
"presentationJson": {
"data": "014000000000000000af5e...",
"meta": {
"notaryUrl": "https://notary.production.vlayer.xyz/v2.0.0",
"websocketProxyUrl": "ws://proxy.vlayer.xyz:80"
},
"version": "2.0.0"
}
}
]
}'
# Extract first proof - production apps should make sure to verify all delivered proofs
PRESENTATION=$(echo "$WEBHOOK_PAYLOAD" | jq '.webProofs[0].presentationJson')Step 2: Verify the presentation
Send the extracted presentation to the verification endpoint:
const verifyResponse = await fetch('https://web-prover.production.vlayer.xyz/api/v2.0/verify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer <your-api-key>'
},
body: JSON.stringify(presentation)
});
const verificationResult = await verifyResponse.json();
console.log(JSON.stringify(verificationResult, null, 2));curl -s -X POST https://web-prover.production.vlayer.xyz/api/v2.0/verify \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <your-api-key>" \
-d "$PRESENTATION" | jq '.'Expected Result
You should receive a JSON response with "success": true and the decoded request/response data (see below). Any other result should be treated as an invalid proof and must halt further processing or workflows.
{
"apiVersion": "v2.0",
"success": true,
"traceId": "1c076b202cde4c9b84df2a9b1695fff3",
"data": {
"serverDomain": "www.amazon.com",
"notaryKeyFingerprint": "a7e62d7f17aa7a22c26bdb93b7ce9400e826ffb2c6f54e54d2ded015677499af",
"tlsTimestamp": 1748535526,
"request": {
"method": "POST",
"url": "/prime-ajax/customername",
"version": "HTTP/1.1",
"headers": [
"accept: application/json",
"content-type: application/json;charset=UTF-8",
"host: XXXXXXXXXXXXXX",
"connection: XXXXX",
"content-length: 91"
],
"body": "{\"location\":\"PrimePageEngagementCXCards/...\"}",
"raw": "504f5354202f7072696d652d616a61782f..."
},
"response": {
"status": 200,
"version": "HTTP/1.1",
"headers": [
"content-type: application/json",
"transfer-encoding: chunked",
"content-encoding: gzip",
"date: Thu, 21 May 2026 14:18:46 GMT"
],
"body": "{\"payload\":{\"fullName\":\"Jane Doe\",\"locale\":\"en-US\"}}",
"raw": "485454502f312e3120323030204f4b..."
}
}
}Sensitive header values are redacted with X characters in the response for
privacy. See redaction configuration for
details.