Generate and verify Reclaim Protocol proofs from Python.
Migrating from
reclaim-python-sdk? This package is the successor toreclaim-python-sdk. The old package is no longer maintained — please use this one going forward. For legacy versions (≤ 1.0.3), see the old package on PyPI.
pip install reclaimprotocol-python-sdkGet your credentials from the Reclaim Developer Portal:
APP_IDAPP_SECRETPROVIDER_ID
import asyncio
from reclaim_python_sdk import ReclaimProofRequest
async def main():
proof_request = await ReclaimProofRequest.init(
app_id="YOUR_APP_ID",
app_secret="YOUR_APP_SECRET",
provider_id="YOUR_PROVIDER_ID",
)
# Set the URL where proofs will be sent
proof_request.set_app_callback_url("https://your-backend.com/receive-proofs")
# URL to show as QR code / deep link to the user
request_url = await proof_request.get_request_url()
print(request_url)
asyncio.run(main())# Add contextual data bound to the proof
proof_request.add_context("0x0", "login for example.com")
# Pre-fill known parameters
proof_request.set_params({"email": "user@example.com"})
# Redirect the user after verification
proof_request.set_redirect_url("https://your-app.com/success")
# Export/import the request (e.g., send to another service)
config = proof_request.to_json_string()
restored = await ReclaimProofRequest.from_json_string(config)Any web framework works. Here's Flask:
from flask import Flask, request, jsonify
from reclaim_python_sdk import verify_proof, Proof
app = Flask(__name__)
@app.post("/receive-proofs")
async def receive_proofs():
proof = Proof.from_json(request.json)
result = await verify_proof(proof, {"providerId": "YOUR_PROVIDER_ID"})
if not result.is_verified:
return jsonify({"error": str(result.error)}), 400
return jsonify({
"extracted_parameters": result.data[0].extracted_parameters,
})
verify_proofaccepts a single proof OR a list of proofs:await verify_proof(proof, config) # single await verify_proof([p1, p2, p3], config) # multiple
Pins verification to a specific provider version. Only providerId is required — providerVersion and allowedTags are optional (pass [] for empty tags):
await verify_proof(proof, {
"providerId": "YOUR_PROVIDER_ID",
"providerVersion": "1.0.0", # optional but recommended
"allowedTags": ["ai"], # optional, can be []
})Fetches the latest expected hashes from the Reclaim backend:
await verify_proof(proof, {"providerId": "YOUR_PROVIDER_ID"})Supply the expected hashes directly — no call to the Reclaim backend:
await verify_proof(proof, {"hashes": ["0x1abc2def3456..."]})Only checks attestor signatures — does NOT validate the proof content:
await verify_proof(proof, {"dangerouslyDisableContentValidation": True})verify_proof always returns a result with:
| Field | Description |
|---|---|
is_verified |
True / False |
error |
Exception if failed, None if passed |
data |
List of TrustedData (context + extracted parameters) |
public_data |
Deduplicated public data from proofs |
pip install pytest pytest-asyncio
pytest tests/Never commit your APP_SECRET or expose it in client-side code.