TypeScript SDK
Current TypeScript SDK reference for Veto Cloud, Charter, Guard, tool registration, provider adapters, and Vercel AI SDK middleware.
Installation
npm install veto-sdkSet an API key for cloud-backed Guard, Charter, and approvals:
export VETO_API_KEY=veto_...Quick Protect
protect() wraps executable tool objects. It supports execute, func, and invoke.
import { protect } from "veto-sdk";
const tools = await protect([
{
name: "issue_refund",
description: "Issue a customer refund",
execute: async ({ amount_usd }: { amount_usd: number }) => {
return { refunded: amount_usd };
},
},
]);Denied or approval-required calls throw ToolCallDeniedError before the original tool executes.
import { ToolCallDeniedError } from "veto-sdk";
try {
await tools[0].execute({ amount_usd: 900 });
} catch (error) {
if (error instanceof ToolCallDeniedError) {
console.error(error.toolName, error.decision, error.message);
}
}Veto.init(options)
Use Veto.init() when you want one client for Guard, Charter, registered tools, and approval polling.
import { Veto } from "veto-sdk";
const veto = await Veto.init({
baseUrl: process.env.VETO_API_URL ?? "https://api.veto.so",
apiKey: process.env.VETO_API_KEY!,
});
const safeTools = veto.wrap(existingExecutableTools);Options:
| Option | Type | Description |
|---|---|---|
apiKey | string | Veto API key. Falls back to VETO_API_KEY. |
baseUrl | string | API URL. Defaults to https://api.veto.so. |
endpoint | string | Alias for baseUrl, useful for self-hosted deployments. |
fetch | typeof fetch | Custom fetch implementation. |
timeoutMs | number | Guard request timeout. |
Missing API keys fail explicitly. The SDK does not silently run tools unguarded.
Guard
Call Guard directly when your framework owns tool execution:
const result = await veto.guard(
"issue_refund",
{ amount_usd: 250 },
{ sessionId: "session-1", agentId: "refund-agent" },
);
if (result.decision === "require_approval") {
console.log(result.approvalId);
}
if (result.receipt) {
console.log(result.receipt.receipt_id);
}Decision receipts
Cloud validation records decision receipts. Export those hosted receipts through GET /v1/receipts/export, then verify the NDJSON offline with the shared veto-receipt-protocol package.
curl "https://api.veto.so/v1/receipts/export?format=ndjson&limit=1000" \
-H "X-Veto-API-Key: $VETO_API_KEY" \
-o receipts.ndjsonimport * as fs from "node:fs";
import {
parseReceiptNdjson,
verifyDecisionReceiptChain,
} from "veto-receipt-protocol";
const receipts = parseReceiptNdjson(await fs.promises.readFile("receipts.ndjson", "utf8"));
const result = verifyDecisionReceiptChain(receipts);
if (!result.ok) {
throw new Error(result.reason);
}Local SDK receipt stores and receipt CLI commands are tracked in the claims manifest and will be documented here after the corresponding SDK/CLI releases land.
Charter
Register the tools your agent can call, then send a Charter turn via REST API. Production policy changes always come back behind a verification link.
await veto.registerTools([
{
name: "issue_refund",
description: "Issue a customer refund",
parameters: [{ name: "amount_usd", type: "number", required: true }],
},
]);
const res = await fetch("https://api.veto.so/v1/charter/turn", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Veto-API-Key": process.env.VETO_API_KEY!,
},
body: JSON.stringify({
message: "Refunds over $200 require support lead approval.",
mode: "compile",
surface: "api",
}),
});
const response = await res.json();
if (response.verification.required) {
console.log(response.verification.linkUrl);
}See Charter SDK for the streaming endpoint and full response contract.
Tool Registration
await veto.registerTools([
{
name: "send_customer_email",
parameters: [
{ name: "to", type: "string", required: true },
{ name: "body", type: "string", required: true },
],
},
]);Vercel AI SDK
Use middleware when model-level tool calls need interception before execute runs.
import { generateText, tool, wrapLanguageModel } from "ai";
import { openai } from "@ai-sdk/openai";
import { Veto } from "veto-sdk";
import { createVetoMiddleware } from "veto-sdk/integrations/vercel-ai";
import { z } from "zod";
const veto = await Veto.init();
const model = wrapLanguageModel({
model: openai("gpt-4.1"),
middleware: createVetoMiddleware(veto),
});
await generateText({
model,
tools: {
issue_refund: tool({
inputSchema: z.object({ amount_usd: z.number() }),
execute: async ({ amount_usd }) => ({ refunded: amount_usd }),
}),
},
prompt: "Refund $250",
});Provider Adapters
Schema adapters are available for framework integration code:
import {
fromAnthropicToolUse,
fromGoogleFunctionCall,
fromMCP,
fromOpenAIToolCall,
isMCPTool,
toAnthropic,
toGoogleTool,
toOpenAI,
} from "veto-sdk";
const openAiTool = toOpenAI({
name: "issue_refund",
parameters: [{ name: "amount_usd", type: "number", required: true }],
});
const anthropicTool = toAnthropic(openAiTool);
const geminiTool = toGoogleTool([openAiTool]);
if (isMCPTool(mcpTool)) {
const normalized = fromMCP(mcpTool);
}
const normalizedCall = fromOpenAIToolCall(toolCall);Exports
| Import | Provides |
|---|---|
veto-sdk | Veto, protect, ToolCallDeniedError, VetoAdmin, guard, approvals, provider adapters, and all core exports |
veto-sdk/cli | CLI utilities — init, learn, compile, test, scan, diff, replay, REPL, Studio |
veto-sdk/providers/adapters | OpenAI, Anthropic, Gemini, and MCP schema/call adapters |
veto-sdk/integrations/vercel-ai | Vercel AI SDK middleware with streaming support |
veto-sdk/integrations/langchain | LangChain tool wrapping |
veto-sdk/integrations/openai-agents | OpenAI Agents integration |
veto-sdk/integrations/browser-use | Browser Use integration |
veto-sdk/rules | Local rule and pipeline utility functions |
veto-sdk/kernel | Local kernel (Ollama) validation client |
veto-sdk/custom | Custom LLM provider client |
veto-sdk/compiler | AST-based policy expression compiler |
veto-sdk/extractors | Entity and content extraction utilities |
veto-sdk/policy | Policy generation utilities |

