Skip to Content
REST APIEndpointsAttestations Endpoints

Attestations Endpoints

Attestations let agents prove claims about their memories to other agents without revealing the actual content. zkStash signs claims with Ed25519, enabling local verification without API calls.

For conceptual overview and use cases, see Attestations Concepts.

Create Attestation

Create a signed attestation about your memories. The attestation can be shared with other agents to prove claims without revealing actual memory content.

Endpoint: POST /attestations

Cost: 3 CC

Request Body

FieldTypeRequiredDescription
claimstringYesThe type of claim to attest.
querystringConditionalSearch query (required for has_memories_matching).
filtersobjectNoFilters for the search (agentId, kind, tags).
thresholdnumberConditionalMinimum count (required for memory_count_gte).
schemaNamestringConditionalSchema name (required for has_schema).
expiresInstringNoAttestation validity duration (default: "24h").

Claim Types

ClaimDescriptionRequired Params
has_memories_matchingAgent has memories matching a queryquery
memory_count_gteAgent has ≥ N memoriesthreshold
has_schemaAgent has a registered schemaschemaName

Example: Prove You Have Matching Memories

{ "claim": "has_memories_matching", "query": "cooking recipes", "filters": { "agentId": "recipe-bot", "kind": "Recipe" }, "expiresIn": "24h" }

Example: Prove Memory Count

{ "claim": "memory_count_gte", "threshold": 10, "filters": { "kind": "Interaction" } }

Example: Prove Schema Exists

{ "claim": "has_schema", "schemaName": "UserProfile" }

Response

{ "success": true, "attestation": { "claim": "has_memories_matching", "params": { "query": "cooking recipes", "filters": { "agentId": "recipe-bot", "kind": "Recipe" } }, "result": { "satisfied": true, "matchCount": 15, "namespace": "0x7f3a9c2b..." }, "issuedAt": 1703123456, "expiresAt": 1703209856, "issuer": "zkstash.ai" }, "signature": "0x...", "publicKey": "0x...", "algorithm": "Ed25519" }

Verifying Attestations

Attestations use Ed25519 signatures and are verified locally—no API call required.

1. Get the Public Key

Fetch the public key once and cache it:

curl https://api.zkstash.ai/.well-known/zkstash-keys.json
{ "attestationPublicKey": "0x...", "algorithm": "Ed25519", "issuedAt": 1703123456789 }

2. Serialize the Attestation

Create a canonical JSON string with sorted keys (deterministic serialization):

{ "claim": "has_memories_matching", "expiresAt": 1703209856, "issuedAt": 1703123456, "issuer": "zkstash.ai", "params": { "filters": { "agentId": "recipe-bot", "kind": "Recipe" }, "query": "cooking recipes" }, "result": { "matchCount": 15, "namespace": "0x7f3a9c2b...", "satisfied": true } }

3. Verify the Signature

Use any Ed25519 library to verify:

Python:

from nacl.signing import VerifyKey import json def verify_attestation(attestation: dict, signature: str, public_key: str) -> bool: # Canonical JSON (sorted keys) message = json.dumps(attestation, sort_keys=True, separators=(',', ':')) # Remove 0x prefix and convert sig_bytes = bytes.fromhex(signature[2:]) key_bytes = bytes.fromhex(public_key[2:]) verify_key = VerifyKey(key_bytes) try: verify_key.verify(message.encode(), sig_bytes) return True except: return False

Node.js (without SDK):

import { verify } from "@noble/ed25519"; function verifyAttestation(attestation, signature, publicKey) { // Canonical JSON (sorted keys) const message = JSON.stringify(attestation, Object.keys(attestation).sort()); const sigBytes = Buffer.from(signature.slice(2), "hex"); const keyBytes = Buffer.from(publicKey.slice(2), "hex"); return verify(sigBytes, Buffer.from(message), keyBytes); }

4. Check Expiration

Always verify expiresAt > currentTime before trusting the attestation.

TypeScript SDK: Use client.verifyAttestation() for a simpler API. See SDK Attestations.


When searching shared memories via grants, the response includes source attestations that prove provenance:

{ "success": true, "memories": [ { "id": "mem_123", "kind": "ResearchFinding", "metadata": { "topic": "AI agents", "contentHash": "0x7f3a9c2b..." }, "source": "shared", "grantor": "0xAgentA..." } ], "sourceAttestations": { "0xAgentA...": { "attestation": { "claim": "shared_memories_from", "params": { "grantor": "0xAgentA...", "memoryHashes": ["0x7f3a9c2b..."] }, "result": { "satisfied": true, "matchCount": 1, "namespace": "0x..." }, "issuedAt": 1703123456, "expiresAt": 1703209856, "issuer": "zkstash.ai" }, "signature": "0x..." } } }

The source attestation proves:

  • Memories came from the claimed grantor’s namespace
  • zkStash vouches for the provenance
  • Memory hashes match what was returned
Last updated on