Behavioral attestation · REST API
Real-time behavioral attestation
A signed proof, made at the moment of the call, that an agent’s HTTPS request was made and what it returned. Nobody has to trust the agent or the party who made the request. Credentials stay hidden, chosen response fields are selectively revealed, and proofs verify off-chain in milliseconds or on-chain on any EVM.
What it is
Real-time behavioral attestation proxies an agent’s HTTPS request through a decentralized attestor. The attestor observes the encrypted TLS session, verifies a zero-knowledge proof of correct decryption, and signs a claim about the response. The result is a portable proof of what the agent did: anyone can confirm what the API returned, and you decide which fields are revealed and which stay hidden. The service is open source as zkfetch-wrapper, which is why the endpoint paths below still say zkfetch.
- Attest any tool call
- a signed claim over exactly what a server returned to the agent
- Hide secrets
- API keys and tokens are cryptographically redacted from the proof
- Selective disclosure
- reveal only the fields you name, redact everything else
- Verify anywhere
- off-chain in milliseconds, or on-chain on any EVM
Quick start
It is a REST service you run. Point at your deployment’s base URL as $ZKFETCH_URL; it holds the Reclaim credentials, so callers send no API key to the service itself. Put every target-API credential in privateOptions.headers so it stays hidden from anyone who inspects the proof.
curl $ZKFETCH_URL/health
# { "status": "ok", "mode": "production", "reclaim_configured": true }curl -X POST $ZKFETCH_URL/zkfetch \
-H 'Content-Type: application/json' \
-d '{
"url": "https://api.example.com/v2/booking/8821",
"publicOptions": { "method": "GET" },
"privateOptions": {
"headers": { "Authorization": "Bearer YOUR_SECRET" },
"responseMatches": [
{ "type": "regex", "value": "\"status\"\\s*:\\s*\"(?<status>[A-Z]+)\"" }
]
},
"redactions": [ { "jsonPath": "$.card_number" } ]
}'From code, reject anything where verified is not true or metadata.mock is set. The full wrapper pattern is in the skill.
Endpoints
A successful /zkfetch returns data, proof, onchainProof, and verified. Store the entire proof object verbatim; it is what verifiers need.
Selective disclosure
Two independent mechanisms, used together. Reveal fields with named regex capture groups, and hide fields with redactions.
Reveal
Each named group in responseMatches becomes a revealed value. Only named groups are disclosed.
{ "type": "regex",
"value": "\"usd\":(?<price>[0-9.]+)" }
// reveals price: "3631.24", nothing elseRedact
Top-level redactions hide bytes cryptographically. Values are removed, not replaced.
{ "jsonPath": "$.user.email" }
{ "regex": "\"card\"\\s*:\\s*\".*?\"" }
// prove success, hide the body:
{ "regex": ".*" }Verify a proof
Anyone holding a stored proof can confirm it. Signature verification is the standard, fast check; add zk verification only when the application demands maximum assurance.
curl -X POST $ZKFETCH_URL/verify \
-H 'Content-Type: application/json' \
-d '{ "proof": <stored proof object> }'
# { "success": true, "valid": true, "extractedData": { "status": "CONFIRMED" } }For smart contracts, /zkfetch already returns an onchainProof. Submit it to a Reclaim verifier contract on Ethereum, Base, Optimism, Polygon, or zkSync Era.
Always confirm real proofs
The service has a mock mode. If its Reclaim credentials are missing, a request still returns success: true with a fake proof that proves nothing. Guard every integration.
- On startup, require GET /health to report mode: production.
- After every /zkfetch, reject the result if metadata.mock is true or verified is not true.
- Never treat success: true on its own as evidence of a valid proof.
This page is the short reference. The full integration guide, including every option and common mistake, is the real-time-behavioral-attestation skill. Hand it to your coding agent.
Questions, or a higher limit: jacob@zeroproofai.com