Docs navigation

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 Ed25519

2 · 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

Treat the API key like a password: keep it server-side, never commit it, and never ship it in browser or mobile code. Rotate it from the dashboard if it leaks — revocation is immediate.

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:

Response from every logged event
{
  "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

Enforce-mode errors (Node.js — Python raises the same classes)
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

In the default monitor mode nothing throws — everything is logged and returned for you to inspect. Start in monitor, watch the dashboard for a day, then switch to enforce.

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.