Documentation

Praxa documentation

Everything to wire up audit logging, understand the tier ladder, and prove — cryptographically, not just by our word — that a chain wasn’t tampered with.

Quickstart by SDK

Pick the SDK you already use. Every wrapper posts one event per call to POST /api/v1/events in the background — the customer’s own call is never blocked or broken by an audit-log failure.

Vercel AI SDK

npm install @piposlabs/praxa-vercel-ai

import { generateText } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { wrapWithAudit } from "@piposlabs/praxa-vercel-ai";

const model = wrapWithAudit(anthropic("claude-sonnet-4-6"), {
  agentId: "agt_xxxxxxxxxxxxxxxxxxxx",
  apiKey: process.env.PRAXA_API_KEY!,
});

const { text } = await generateText({ model, prompt: "Hello" });
// -> audit event posted to Praxa in the background

OpenAI Node SDK

npm install @piposlabs/praxa-openai-sdk

import OpenAI from "openai";
import { wrapChatCompletionsCreate } from "@piposlabs/praxa-openai-sdk";

const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const auditedCreate = wrapChatCompletionsCreate(openai, {
  agentId: "agt_xxxxxxxxxxxxxxxxxxxx",
  apiKey: process.env.PRAXA_API_KEY!,
});

const completion = await auditedCreate({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello" }],
});

Anthropic Node SDK

npm install @piposlabs/praxa-anthropic-sdk

import Anthropic from "@anthropic-ai/sdk";
import { wrapMessagesCreate } from "@piposlabs/praxa-anthropic-sdk";

const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
const auditedCreate = wrapMessagesCreate(anthropic, {
  agentId: "agt_xxxxxxxxxxxxxxxxxxxx",
  apiKey: process.env.PRAXA_API_KEY!,
});

const msg = await auditedCreate({
  model: "claude-sonnet-4-6",
  max_tokens: 1000,
  messages: [{ role: "user", content: "Hello" }],
});

LangChain (Node/TS)

npm install @piposlabs/praxa-langchain

import { ChatOpenAI } from "@langchain/openai";
import { createPraxaCallbackHandler } from "@piposlabs/praxa-langchain";

const praxaCallback = createPraxaCallbackHandler({
  agentId: "agt_xxxxxxxxxxxxxxxxxxxx",
  apiKey: process.env.PRAXA_API_KEY!,
});

const model = new ChatOpenAI({ modelName: "gpt-4o", callbacks: [praxaCallback] });
await model.invoke([{ role: "user", content: "Hello" }]);

Don’t see your stack? Call POST /api/v1/events directly from anything that can POST JSON — see the request shape in the Article 12 implementation guide.

Concepts

TermMeaning
AgentA logical grouping for one AI feature in your app — e.g. “Customer Support Bot”. Register once, get a UUID; every event references it.
EventA single AI-agent decision: input + output + model + rationale + downstream effects, SHA-256 chained to the previous event for the same agent.
ChainThe append-only hash chain of events per agent. Any tampering breaks continuity from that point forward and is detectable by re-verifying.
AnchorA periodic, Ed25519-signed snapshot of the chain head, so an auditor can prove your chain state at time T without trusting our runtime.
ReportA compliance evidence pack generated from your real events: NIST AI RMF / EU AI Act Annex IV / SOC 2 evidence.

Tier limits

FreeStarterBusinessEnterprise
Price$0$79/mo$249/moContact sales
Agents1525Unlimited
Events / month10,000100,0001,000,000Unlimited
Retention30 days1 year7 yearsCustom
Webhook delivery
NIST AI RMF report
EU AI Act Annex IV / SOC 2 kit

POST /api/v1/events returns 429 once you hit your monthly cap, with X-RateLimit-* headers. Nothing already ingested is dropped. See full pricing for plan details.

Verifying a chain (standalone)

Every event’s entry_hash is a SHA-256 over the event payload plus the previous event’s hash, so tampering anywhere breaks continuity from that point forward. You — or your auditor — can verify any exported chain without trusting Praxa’s runtime, using the open-source, MIT-licensed @piposlabs/praxa-verify (zero runtime dependencies, ~150 lines — read it, audit it, run it on your own export):

# Export your chain, then verify locally — no network call needed:
npx @piposlabs/praxa-verify chain-export.json

# Or pipe it straight from the API:
curl -H "Authorization: Bearer $PRAXA_API_KEY" \
  "https://praxa.piposlab.com/api/v1/agents/<id>/export" \
  | npx @piposlabs/praxa-verify --stdin

Exit code 0 = chain verified, 1 = tampering detected. Anchors are additionally signed with Ed25519 — verify an anchor signature against our public key at /api/v1/pubkey.

Outbound webhooks

Starter tier and above: subscribe a URL at /settings/webhooks to receive every successful event ingest as an HMAC-signed POST — mirror your audit trail into Splunk, Datadog, or your own BI stack without polling the API. The signature format is Stripe-compatible:

import { createHmac, timingSafeEqual } from "node:crypto";

function verifyPraxaWebhook(body: string, header: string, secret: string) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const expected = createHmac("sha256", secret)
    .update(`${parts.t}.${body}`)
    .digest("hex");
  if (!timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1))) {
    throw new Error("signature_mismatch");
  }
}

Retention & purge

Retention is customer-controlled per agent (Business+) or per tenant (all tiers), from 1 day to forever. Praxa never hard-deletes a chain entry — at purge time only the payload (input_payload / output_payload) is scrubbed; the hash-chain bookkeeping (entry_hash, previous_hash, chain_position) is preserved forever, so the chain keeps verifying end-to-end even after payloads age out.

Support

Email alex@piposlab.com for anything that needs a human — integration help, a verification question, or a false-positive report on praxa-verify.

Start freeSee pricing