Skip to main content
The official Node.js SDK for VaultGraph, the trust and verification platform for AI agents. Use this SDK to:
  • sign and submit deployment-scoped JobReceipts from your backend
  • integrate VaultGraph with LangChain.js or the Vercel AI SDK
  • manage agents through the VaultGraph API
  • verify exported receipt signatures offline

Install

pnpm add @vaultgraph/sdk
Also works with npm install @vaultgraph/sdk or yarn add @vaultgraph/sdk.

Before you start

Before you submit receipts, make sure you have:
  1. Signed up at app.vaultgraph.com and created your organization
  2. Followed the full Setup flow
  3. Created an agent in the platform or via the API
  4. Created a deployment for that agent in the portal UI
  5. Registered your public key as an active signing key on that deployment
Receipt ingestion is deployment-scoped, so every submission must include the deployment short ID as deploymentId. In practice, most integrations need these environment variables:
  • VAULTGRAPH_API_KEY
  • VAULTGRAPH_DEPLOYMENT_ID
  • VAULTGRAPH_PRIVATE_KEY
If you do not already have an Ed25519 key pair, the SDK also exports generateKeyPair().

Quick start

Submit your first signed receipt in under 10 lines:
import { submitSignedReceipt, hashContext } from "@vaultgraph/sdk";

const { response } = await submitSignedReceipt({
  apiKey: process.env.VAULTGRAPH_API_KEY!,
  deploymentId: process.env.VAULTGRAPH_DEPLOYMENT_ID!, // dep_...
  privateKey: process.env.VAULTGRAPH_PRIVATE_KEY!,
  jobId: "job-001",
  resolution: "success",
  contextHash: hashContext({ transcript: "..." }),
  metadata: { channel: "email" },
});

console.log(response); // { id: "receipt-id" }
This helper builds the canonical JobReceipt, signs it with your Ed25519 private key, derives the matching public key automatically, and submits the signed payload to VaultGraph.

Choose an integration style

Use whichever path matches your application: The LangChain and AI SDK integrations both support deriveJobId(...), deriveMetadata(...), and deriveResolution(...) hooks so you can align VaultGraph receipts with your own run IDs, metadata, and outcome rules.

Idempotency and duplicate suppression

The autogenerated integration job IDs (lc-* and ai-*) are convenient for local testing, but they are not retry-safe. If the same logical job can be retried, replayed, or resumed, provide deriveJobId(...) and return a stable vendor-controlled identifier. Recommended pattern:
  • reuse the same job_id for the same logical job across retries
  • put attempt counters, worker IDs, or retry reasons in metadata, not in job_id
  • if one framework invocation can emit multiple integration events, decide whether you want one receipt per logical job or one receipt per framework event, then encode that intentionally in job_id
Examples:
  • LangChain: use context.runId or a request ID passed through chain inputs
  • AI SDK: create middleware inside the request or job boundary and close over your own request ID
import { vaultgraph } from "@vaultgraph/sdk/ai";

const requestId = "req_123";

const middleware = vaultgraph({
  apiKey: process.env.VAULTGRAPH_API_KEY!,
  deploymentId: process.env.VAULTGRAPH_DEPLOYMENT_ID!, // dep_...
  privateKey: process.env.VAULTGRAPH_PRIVATE_KEY!,
  deriveJobId: ({ type }) => `${requestId}:${type}`,
});
For LangChain specifically, nested chains and agents may trigger more than one callback for what your product considers a single job. The VaultGraph handler submits only for the top-level LangChain run by default. Set includeNestedRuns: true only if you intentionally want one receipt per nested callback as well.
import { VaultGraphCallbackHandler } from "@vaultgraph/sdk/langchain";

const handler = new VaultGraphCallbackHandler({
  apiKey: process.env.VAULTGRAPH_API_KEY!,
  deploymentId: process.env.VAULTGRAPH_DEPLOYMENT_ID!, // dep_...
  privateKey: process.env.VAULTGRAPH_PRIVATE_KEY!,
  deriveJobId: (_output, context) => `lc:${context.runId}`,
  deriveMetadata: (_output, context) => ({
    source: "langchain",
    event: context.event,
    runId: context.runId,
  }),
  deriveResolution: (_output, context) => context.defaultResolution,
});
See the integration guides for complete LangChain and AI SDK examples.

Manual receipt flow

If you need more control than the one-liner above, create, sign, verify, and submit receipts separately:
import {
  createReceipt,
  derivePublicKeyPem,
  hashContext,
  signReceipt,
  verifyReceipt,
  submitReceipt,
} from "@vaultgraph/sdk";

const privateKey = process.env.VAULTGRAPH_PRIVATE_KEY!;

// 1. Hash sensitive context locally. Raw context is never sent to VaultGraph.
const contextHash = hashContext({ transcript: "..." });

// 2. Build the canonical receipt.
const receipt = createReceipt({
  jobId: "job-001",
  resolution: "success",
  contextHash,
  metadata: { channel: "email" },
});

// 3. Sign with your Ed25519 private key.
const signature = signReceipt({
  receipt,
  privateKey,
});

// 4. Derive the matching public key.
const publicKey = derivePublicKeyPem(privateKey);

// 5. Verify locally if you want an extra debugging step.
const ok = verifyReceipt({
  receipt,
  signature,
  publicKey,
});

// 6. Submit to VaultGraph.
await submitReceipt({
  receipt,
  signature,
  publicKey,
  apiKey: process.env.VAULTGRAPH_API_KEY!,
  deploymentId: process.env.VAULTGRAPH_DEPLOYMENT_ID!, // dep_...
});

Create and sign without submitting

import { createSignedReceipt } from "@vaultgraph/sdk";

const { receipt, signature } = createSignedReceipt({
  jobId: "job-001",
  resolution: "success",
  contextHash: "abc123",
  privateKey: process.env.VAULTGRAPH_PRIVATE_KEY!,
  metadata: { channel: "sms" },
});

Verify exported receipts

If you export receipts from the platform as JSON, each item includes the canonical receipt payload and its signature. You can verify them offline with the public key that was registered on the deployment:
import { verifyReceipt } from "@vaultgraph/sdk";

for (const item of exportedReceipts) {
  const valid = verifyReceipt({
    receipt: item.receipt,
    signature: item.signature,
    publicKey: item.signing_public_key,
  });
  console.log(item.receipt.job_id, valid ? "valid" : "INVALID");
}

Manage agents

Use the agents client for control-plane operations against /api/agents:
import { createAgentsClient } from "@vaultgraph/sdk";

const agents = createAgentsClient({
  apiKey: process.env.VAULTGRAPH_API_KEY!,
});

// Create
const agent = await agents.create({
  name: "Support Bot",
  description: "Handles tier-1 support workflows.",
});

// List and get
const all = await agents.list();
const detail = await agents.get(agent.id);

// Update
await agents.update(agent.id, {
  name: "Support Bot v2",
});

// Delete
await agents.delete(agent.id);
Use the API key for control-plane operations such as creating agents. Use the same API key together with deploymentId when submitting receipts.

API reference

Receipt functions

FunctionDescription
hashContext(value, options?)SHA-256 hash of canonical JSON or bytes
createReceipt(input)Build a normalized JobReceipt
serializeReceipt(receipt)Canonical JSON string of a receipt
signReceipt(options)Sign a receipt and return a base64 signature
verifyReceipt(options)Verify a receipt signature and return a boolean
createSignedReceipt(options)Create and sign in one step
submitSignedReceipt(options)Create, sign, and submit in one step
submitReceipt(options)POST a signed receipt to /api/receipts
generateKeyPair()Generate a PEM-encoded Ed25519 key pair

Client factories

FunctionDescription
createAgentsClient(options)CRUD for /api/agents

Types

Receipts: CreateReceiptInput, JobReceipt, JobReceiptV0, JobResolution, ReceiptVersion, SubmitReceiptOptions, SubmitReceiptResponse, CreateSignedReceiptOptions, SubmitSignedReceiptOptions, ApiError Agents: AgentRecord, AgentCreateInput, AgentUpdateInput, AgentsClient, AgentsClientOptions

Important notes

  • Never send raw context: hash it locally with hashContext() first
  • Server-side only: keep your private key and API key out of browser code
  • Deployment key pinning: submitted publicKey values must match an active signing key registered on the target deployment
  • Receipt version: the current receipt format is v0; breaking changes will bump the major SDK version
  • Ed25519 only: RSA and ECDSA are not supported for receipt signing