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/v1/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 requestoutputs
: 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 Getting Started guide or 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",
outputs: {
// ...
},
webProofs: [
{
outputs: { /* ... */ },
decodedTranscript: { /* ... */ },
presentationJson: {
data: "014000000000000000db...",
meta: {
notaryUrl: "https://notary.example.com/v0.1.0-alpha.12",
websocketProxyUrl: "wss://proxy.example.com"
},
version: "0.1.0-alpha.12"
}
}
]
};
// 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",
"outputs": {
// ...
},
"webProofs": [
{
"outputs": { "..." },
"decodedTranscript": { "..." },
"presentationJson": {
"data": "014000000000000000db...",
"meta": {
"notaryUrl": "https://notary.example.com/v0.1.0-alpha.12",
"websocketProxyUrl": "wss://proxy.example.com"
},
"version": "0.1.0-alpha.12"
}
}
]
}'
# 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.vlayer.xyz/api/v1/verify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-client-id': '4f028e97-b7c7-4a81-ade2-6b1a2917380c',
'Authorization': 'Bearer jUWXi1pVUoTHgc7MOgh5X0zMR12MHtAhtjVgMc2DM3B3Uc8WEGQAEix83VwZ'
},
body: JSON.stringify(presentation)
});
const verificationResult = await verifyResponse.json();
console.log(JSON.stringify(verificationResult, null, 2));
curl -s -X POST https://web-prover.vlayer.xyz/api/v1/verify \
-H "Content-Type: application/json" \
-H "x-client-id: 4f028e97-b7c7-4a81-ade2-6b1a2917380c" \
-H "Authorization: Bearer jUWXi1pVUoTHgc7MOgh5X0zMR12MHtAhtjVgMc2DM3B3Uc8WEGQAEix83VwZ" \
-d "$PRESENTATION" | jq '.'
The included credentials are for limited public use. For production use, please contact our team.
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.
{
"success": true,
"serverDomain": "example.com",
"notaryKeyFingerprint": "0000000000000000000000000000000000000000000000000000000000000000",
"request": {
"method": "POST",
"url": "/api/v2/order/details",
"version": "HTTP/1.1",
"headers": [
["content-type", "application/json"],
["accept", "*/*"],
["host", "XXXXXXXXXXXXXXX"],
["connection", "XXXXX"]
],
"body": "{\"orderNumber\":\"00000000000000000000\",\"createTime\":0}",
"raw": "504f5354202f626170692f...",
"parsingSuccess": true
},
"response": {
"status": 200,
"version": "HTTP/1.1",
"headers": [
["content-type", "application/json"],
["content-length", "2543"],
["content-encoding", "gzip"],
["date", "Mon, 01 Jan 2024 00:00:00 GMT"]
],
"body": "{\"code\":\"000000\",\"message\":null,\"data\":{\"orderNumber\":\"00000000000000000000\",\"asset\":\"USDT\",\"amount\":\"0.00000000\",...}}",
"raw": "485454502f312e3120323030204f4b...",
"parsingSuccess": true
}
}
Sensitive header values are redacted with X
characters in the response for
privacy. See redaction configuration for
details.