vlayer docs
REST API

POST /prove

Generate Web Proof (v2)

POST /api/v2.0/prove

Generate a cryptographic Web Proof by making a notarized HTTP request to the specified URL.

Authentication

Requests require header:

  • Authorization: Bearer <api-key>: Your API key

Request Body

All field names must be in camelCase. Unknown fields are rejected with a 400 error.

  • url: HTTPS URL to make a request to and generate a proof for. Only HTTPS URLs are supported
  • method: HTTP method to use for the request. Defaults to GET. Supported values: GET, POST, PUT, DELETE, PATCH, HEAD, CONNECT, OPTIONS, TRACE
  • headers: Array of HTTP headers formatted as "Header-Name: Header-Value"
  • body: Request body data for POST requests as a string
  • notaryUrl: URL of the notary server for TLS notarization. Defaults to https://notary.vlayer.xyz/v0.1.0-alpha.12
  • maxRecvData: Optional maximum number of bytes to receive from the server. Must not exceed 92160
  • redaction: Optional array of redaction rules controlling which parts of the request and response are revealed in the Web Proof (see below)

Redaction

Redaction lets you hide sensitive data — like API keys or tokens — from the Web Proof, so third parties who verify it never see those values.

Each rule in the redaction array targets request and/or response, and rules accumulate across the array.

Every field supports two mutually exclusive modes: a denylist (list what to hide, revealing everything else) or the matching *_except allowlist (list what to reveal, hiding everything else). Listing both a denylist and an allowlist for the same field is rejected with a 400. A field named in neither reveals everything.

Field names inside a redaction rule are snake_case (e.g. headers_except, url_query, json_body), unlike the camelCase top-level request fields.

Supported fields:

FieldReveal-all-butRedacts
request.headersrequest.headers_exceptRequest headers
request.url_queryrequest.url_query_exceptRequest URL query parameters
response.headersresponse.headers_exceptResponse headers
response.json_bodyresponse.json_body_exceptJSON fields in the response body

Four headers are always revealed in both the request and the response, regardless of redaction rules: content-length, transfer-encoding, content-type, and content-encoding. They carry no secrets and are required to verify the proof. Listing one of them in a denylist has no effect, and *_except allowlists reveal them automatically.

Response Body

Success

{
  "apiVersion": "v2.0",
  "success": true,
  "data": {
    "data": "<hex-encoded proof>",
    "version": "0.1.0-alpha.12",
    "meta": {
      "notaryUrl": "https://notary.vlayer.xyz/v0.1.0-alpha.12"
    }
  }
}
  • apiVersion: API version string
  • success: true
  • data.data: Hex-encoded proof data
  • data.version: TLSN protocol version used
  • data.meta.notaryUrl: Notary server URL that was used

Error

{
  "apiVersion": "v2.0",
  "success": false,
  "error": {
    "code": "INVALID_REQUEST",
    "message": "Invalid request: ..."
  }
}
  • error.code: Machine-readable error code. Possible values:
    • INVALID_REQUEST — malformed request body (400)
    • INTERNAL_SERVER_ERROR — server-side failure (500)
  • error.message: Human-readable description. The values returned here may change over time, use error.code for stable error indication

Examples

Binance public API call

curl -X POST https://web-prover.production.vlayer.xyz/api/v2.0/prove \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <your-api-key>" \
  -d '{
    "url": "https://data-api.binance.vision/api/v3/exchangeInfo?symbol=ETHUSDC",
    "headers": []
  }'
const response = await fetch('https://web-prover.production.vlayer.xyz/api/v2.0/prove', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer <your-api-key>'
  },
  body: JSON.stringify({
    url: 'https://data-api.binance.vision/api/v3/exchangeInfo?symbol=ETHUSDC',
    headers: []
  })
});

const result = await response.json();
console.log(result);

Response:

{
  "apiVersion": "v2.0",
  "success": true,
  "data": {
    "data": "014000000000000000899cdccd31337c96bb9e519aa438ed73cdb47dda5c80e995ef0a1c04bf6c563730cde41724dafc1391b1b81acc5d989a7f7add8...",
    "version": "0.1.0-alpha.12",
    "meta": {
      "notaryUrl": "https://notary.vlayer.xyz/v0.1.0-alpha.12"
    }
  }
}

Gmail API call with redaction

This example makes an authenticated Gmail API request while redacting the Authorization header from the proof:

curl -X POST https://web-prover.production.vlayer.xyz/api/v2.0/prove \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <your-api-key>" \
  -d '{
    "url": "https://gmail.googleapis.com/gmail/v1/users/me/messages/<email-id>?format=raw",
    "headers": [
      "Authorization: Bearer <gmail-token>"
    ],
    "redaction": [
      {
        "request": {
          "headers": ["authorization"]
        }
      }
    ]
  }'
const response = await fetch('https://web-prover.production.vlayer.xyz/api/v2.0/prove', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer <your-api-key>'
  },
  body: JSON.stringify({
    url: 'https://gmail.googleapis.com/gmail/v1/users/me/messages/<email-id>?format=raw',
    headers: [
      'Authorization: Bearer <gmail-token>'
    ],
    redaction: [
      {
        request: {
          headers: ['authorization']
        }
      }
    ]
  })
});

Redacting request, response, and body fields

Redaction rules can target the request and response together. This example redacts a request header and query parameter, reveals only the content-type response header, and keeps only the balance field of the JSON response body:

{
  "url": "https://api.example.com/account?token=secret",
  "headers": ["Authorization: Bearer <token>"],
  "redaction": [
    {
      "request": {
        "headers": ["authorization"],
        "url_query": ["token"]
      },
      "response": {
        "headers_except": ["content-type"],
        "json_body_except": ["balance"]
      }
    }
  ]
}