Quickstart
From zero to a signed, policy-checked, replayable audit trail in under 10 minutes. Works beside any agent framework — nothing about your agent loop changes.
1 · Install the SDK
npm install @proofledger/sdk # Node 18+
pip install 'proofledger[signing]' # Python 3.9+; [signing] enables Ed255192 · Create an API key
In the dashboard, open API Keys and create a key. It is shown once — store it as PROOFLEDGER_API_KEY in your environment. The key identifies your project, so you never pass a project id in code.
Security
3 · Register, log, check policy
import { ProofLedger } from "@proofledger/sdk";
// 1. Enable once at startup. The API key resolves your project.
ProofLedger.enable({
apiKey: process.env.PROOFLEDGER_API_KEY,
baseUrl: "https://www.proofledger.dev",
agentName: "support-agent",
owner: "customer-success",
framework: "custom", // langchain | crewai | openai-agents | claude-code | custom
model: "gpt-4.1",
version: "1.0.0",
policyMode: "monitor", // switch to "enforce" when you're ready to gate actions
});
// 2. Register the agent's identity. Generates an Ed25519 keypair —
// the private key stays in this process and signs every event.
await ProofLedger.registerAgent();
// 3. Start a workflow and log what the agent does.
const workflowId = "wf_refund_" + Date.now();
await ProofLedger.logWorkflowStep({
workflowId,
workflowName: "Customer refund request",
eventType: "task_received",
action: "Received refund request for order ORD-123",
});
await ProofLedger.logToolCall({
workflowId,
toolName: "refund_lookup",
inputSummary: "orderId=ORD-123",
outputSummary: "eligible=true, amount=$49",
});
// 4. Check policy BEFORE a risky action (no event logged, no trust change).
const policy = await ProofLedger.evaluatePolicy({
toolName: "issue_refund",
sensitiveAction: true,
});
if (policy.decision === "allow") {
await ProofLedger.logDecision({
workflowId,
action: "Refund approved under policy",
outputSummary: "$49 refunded to customer",
});
}
// 5. Record which model actually executed (provenance — the agent keeps its
// identity and trust even when this changes).
await ProofLedger.recordModelExecution({
provider: "openai", modelName: "gpt-4.1",
inputTokens: 812, outputTokens: 214,
estimatedCostUsd: 0.012, latencyMs: 2100,
});
// 6. Record the verified outcome. verificationMethod is REQUIRED —
// agents never silently self-declare success.
await ProofLedger.recordOutcome({
taskType: "refund-request",
status: "success",
verificationMethod: "deterministic", // refund confirmed via payments API
businessValueEstimate: 49,
});
// 7. Finish the workflow and flush before exit.
await ProofLedger.logWorkflowStep({
workflowId,
action: "Refund issued",
status: "completed",
});
await ProofLedger.flush();
// 8. Live trust score, any time.
const trust = await ProofLedger.getTrustScore();
console.log(trust); // { trustScore: 100, trustLevel: "trusted", status: "active" }Every log* call runs the full trust pipeline server-side: signature verification → tool registry lookup → policy evaluation → security events → trust scoring → append to the agent's tamper-evident hash chain. The response tells you what happened:
{
"event": { "eventId": "evt_…", "policyDecision": "allow", "hash": "8d8f…", … },
"policy": { "decision": "allow", "matched": [...], "reason": "…" },
"trust": { "before": 100, "after": 100, "level": "trusted" }
}4 · See it in the dashboard
Open Agents — your agent appears with a live trust score. Click through for the identity card, trust breakdown, model portability history, runtime timeline, and the Replay ▶ button that steps through your workflow. Models shows per-model cost, latency, and fallbacks; Outcomes shows verified results and value-to-cost. The Audit trail page has a Verify chain button that recomputes every hash.
Error handling
import { PolicyBlockedError, ApprovalDeniedError } from "@proofledger/sdk";
try {
await ProofLedger.logToolCall({ toolName: "unregistered_tool" });
} catch (err) {
if (err instanceof PolicyBlockedError) {
// enforce mode: policy said block. The blocked attempt IS logged.
console.warn("Blocked:", err.evaluation.reason);
} else if (err instanceof ApprovalDeniedError) {
// enforce mode: a human denied (or the approval timed out — fail closed).
console.warn("Not approved:", err.status);
} else {
// Network/HTTP errors throw plain Errors with the status + body.
throw err;
}
}Note
Production checklist
Production
- Register your real tools in Tools & MCP and approve them — unknown tools are blocked by policy.
- Persist the agent's private key (from registerAgent()) in your secret manager and load it with identifyAgent(id, privateKey) so restarts keep the same identity.
- Call flush() on shutdown so no events are lost.
- Rate limits: 300 events/min per project (HTTP 429 + Retry-After), 64 KB max body. Send summaries, not full payloads.
- Switch policyMode to "enforce" once your policies are tuned.