Quickstart
Create a project, mint a scoped key, install the SDK, send your first event, and pull a signed verification receipt.
Five minutes from nothing to a verifiable trail.
Create a project
Sign up at audkit.dev and create a project from /dashboard. A
project is the isolation unit: its own API keys, members, retention policy, and its own
Merkle tree, which starts at sequence 1.
Each project actually keeps two append-only streams, each with its own tree:
events— the audit log your application writes.project_audit— Audkit's own control-plane record for that project (key creation and revocation, member changes, retention changes, legal holds). Reachable asstream=project-auditin the API.
Mint a scoped API key
Open Project → Settings → API Keys, create a key, and copy it — it is shown once.
Scopes are enforced per endpoint, so give each service the narrowest key that works:
| Scope | Grants |
|---|---|
log:write | POST /api/v1/log — ingest events |
log:read | GET /api/v1/events, legal-hold proofs |
log:export | GET /api/v1/export |
log:verify | GET /api/v1/verify, /root, /proof/*, /anchors |
Set it in your environment:
AUDKIT_API_KEY="..."
# Optional. Defaults to https://audkit.dev
AUDKIT_BASE_URL="https://audkit.dev"Install the SDK
npm install audkitThe package ships four entrypoints — audkit (the client), audkit/nextjs,
audkit/ai, and audkit/protocol (the raw canonicalization, Merkle, and Ed25519
primitives) — plus an npx audkit CLI for offline verification and key generation.
Send your first event
import { Audkit } from "audkit";
export const audit = new Audkit({ apiKey: process.env.AUDKIT_API_KEY! });import { audit } from "./audit";
const { id, status } = await audit.log({
action: "invoice.approved",
actor: { type: "user", id: user.id, display: user.email },
target: { type: "invoice", id: invoice.id },
risk: "medium",
metadata: { amountCents: invoice.amountCents },
});
console.log(id, status); // evt_… sealedstatus is always "sealed": the event was sequenced and committed to the Merkle tree
before the server responded. action and actor are the only required fields — see
LogInput for the rest.
Read it back:
const { events } = await audit.query({ action: "invoice.approved", limit: 50 });Or drill into an entity — what it did (outgoing) versus what happened to it
(incoming):
const { events } = await audit.query({
entityType: "user",
entityId: user.id,
direction: "outgoing",
});Prefer to wrap code you already have instead of calling log() by hand? Pick the wrapper
that matches where the mutation lives:
| Where the action happens | Import | Wrapper |
|---|---|---|
| Next.js route handler | audkit/nextjs | withAuditLogging() |
| Next.js Server Action | audkit/nextjs | withAuditAction() |
| AI agent tool call | audkit/ai | auditedTool() |
| Anywhere else | audkit | audit.log() |
Verify
Ask the platform to rebuild the tree from row content and hand back a service-signed receipt:
const receipt = await audit.verify();
receipt.valid; // true — every leaf rebuilt from sequence 1
receipt.checkedCount; // leaves rebuilt
receipt.treeSize; // size of the tree they reproduce
receipt.rootHash; // the root they reproduce
receipt.firstBreak; // null, or { sequence, reason, detail }
receipt.signature; // Ed25519 over the receipt, by the service keyA platform grading itself proves little on its own, so the client also checks the
platform's work without asking. checkConsistency() fetches the current signed tree head
and proves — with local hash arithmetic, no trust in the response — that it still contains
the head this client last pinned:
await audit.checkConsistency(); // throws AudkitTamperError if it doesn'tThis runs automatically (throttled) after log() and query(). Keep going in
Verification for receipts, proofs, customer-held signing keys, and
the fully offline npx audkit verify full rebuild.
Next steps
Audit your AI agents
Risk labels, required reasons, and authorization gates on every tool call.
Audit Next.js
Route handlers and Server Actions, with resolvers for actor, target, and metadata.
SDK reference
Every constructor option, method, and error type.
REST API
Call the endpoints directly, from any language.
What is Audkit?
Tamper-evident audit logging for TypeScript apps and AI agents — every event sequenced and committed to an RFC 6962 Merkle tree before the API answers.
AI agent tools
auditedTool() wraps an AI SDK tool so every agent call enters the audit record — with risk labels, required reasons, and an authorization gate.