TypeScript SDK Quick Start
The TruthVouch TypeScript SDK provides drop-in replacements for OpenAI, Anthropic, and Google AI providers. All LLM calls are automatically governed with fact-checking, PII detection, and policy enforcement. Works in Node.js and modern browsers.
Installation
npm install @truthvouch/sdk# oryarn add @truthvouch/sdk# orpnpm add @truthvouch/sdkRequires Node.js 18+ or modern browser with ES2020+ support.
Basic Setup
1. Get an API Key
- Go to TruthVouch dashboard → Settings → API Keys
- Click Generate New Key
- Choose a Test key for development, Live key for production
- Copy the key (it won’t be shown again)
2. Store the Key Securely
In Node.js, use environment variables:
TRUTHVOUCH_API_KEY=tv_live_7e9c4a2b8f1d5c3a9e7b2f4d6c1a8e3bLoad it:
import TruthVouch from '@truthvouch/sdk';import 'dotenv/config';
const apiKey = process.env.TRUTHVOUCH_API_KEY || '';In browsers, pass the key directly (or fetch from your backend):
const apiKey = await fetch('/api/truthvouch-key').then(r => r.text());3. Initialize the Client
import TruthVouch from '@truthvouch/sdk';
const tv = new TruthVouch({ apiKey: process.env.TRUTHVOUCH_API_KEY});Drop-In Provider Replacement
OpenAI
Before (direct OpenAI):
import OpenAI from 'openai';
const openai = new OpenAI();const completion = await openai.chat.completions.create({ model: 'gpt-4o', messages: [{ role: 'user', content: 'What is quantum computing?' }],});console.log(completion.choices[0].message.content);After (with TruthVouch governance):
import TruthVouch from '@truthvouch/sdk';
const tv = new TruthVouch({ apiKey: 'tv_live_...' });const openai = tv.openai();
const completion = await openai.chat.completions.create({ model: 'gpt-4o', messages: [{ role: 'user', content: 'What is quantum computing?' }],});
console.log(completion.choices[0].message.content);console.log('Verdict:', (completion as any).governance.verdict);Zero code changes to your prompt, temperature, max_tokens, or other parameters — the API is identical.
Anthropic
const tv = new TruthVouch({ apiKey: 'tv_live_...' });const anthropic = tv.anthropic();
const message = await anthropic.messages.create({ model: 'claude-3-5-sonnet-20241022', max_tokens: 1024, messages: [{ role: 'user', content: 'Explain AI governance' }],});
console.log(message.content[0].type === 'text' ? message.content[0].text : '');Google AI
const tv = new TruthVouch({ apiKey: 'tv_live_...' });const google = tv.google();
const response = await google.generateContent('Explain AI governance', { model: 'gemini-1.5-pro',});
console.log(response.text());Streaming
Stream responses with governance applied:
const tv = new TruthVouch({ apiKey: 'tv_live_...' });const openai = tv.openai();
const stream = await openai.chat.completions.create({ model: 'gpt-4o', messages: [{ role: 'user', content: 'Write a haiku about AI' }], stream: true,});
for await (const chunk of stream) { if (chunk.choices[0]?.delta?.content) { process.stdout.write(chunk.choices[0].delta.content); }}
const report = (stream as any).governanceReport;console.log(`\nVerdict: ${report.verdict}`);console.log(`Alerts: ${report.alerts.length}`);Manual Content Scanning
For post-hoc fact-checking of any text:
const tv = new TruthVouch({ apiKey: 'tv_live_...' });
const result = await tv.scan({ prompt: 'Tell me about the founding of NASA', response: 'NASA was founded in 1958 by President Eisenhower',});
console.log(`Verdict: ${result.verdict}`);console.log(`Trust Score: ${result.trustScore}`);console.log(`Alerts: ${result.alerts.length}`);
result.alerts.forEach(alert => { console.log(` - ${alert.severity}: ${alert.message}`);});Response format:
interface ScanResult { verdict: 'allowed' | 'blocked' | 'warning'; trustScore: number; // 0.0 to 1.0 alerts: Alert[]; piiDetected: boolean; piiEntities: PIIEntity[];}Batch Scanning
For scanning large datasets offline:
const tv = new TruthVouch({ apiKey: 'tv_live_...' });
// Submit a batch jobconst job = await tv.batch.submit({ sourceUrl: 's3://my-bucket/documents.jsonl', format: 'jsonl', scanMode: 'deep', // 'fast', 'standard', or 'deep' callbackUrl: 'https://myapp.com/webhooks/scan-complete', // optional});
console.log(`Job ID: ${job.id}`);console.log(`Status: ${job.status}`);
// Poll for statuslet completed = false;while (!completed) { const status = await tv.batch.getStatus(job.id); console.log(`Progress: ${status.progressPercent}% (${status.scanned}/${status.total})`);
if (status.completed) { console.log(`Flagged items: ${status.flaggedCount}`); completed = true; } else { await new Promise(r => setTimeout(r, 10000)); // Wait 10s }}Input format (JSONL):
{"prompt": "Tell me about Paris", "response": "Paris is the capital of France"}{"prompt": "What is 2+2?", "response": "2+2 equals 4"}Error Handling
Handle governance blocks and other errors:
import TruthVouch, { PolicyBlockedError, GatewayUnreachableError, AuthenticationError, RateLimitError,} from '@truthvouch/sdk';
try { const response = await tv.openai.chat.completions.create({ model: 'gpt-4o', messages: [{ role: 'user', content: '...' }], });} catch (error) { if (error instanceof PolicyBlockedError) { console.log(`Blocked by policy: ${error.governanceReport.policyId}`); } else if (error instanceof RateLimitError) { console.log(`Rate limited, retry after ${error.retryAfter}s`); } else if (error instanceof GatewayUnreachableError) { console.log(`Gateway unreachable: ${error.message}`); } else if (error instanceof AuthenticationError) { console.log(`Auth failed: ${error.message}`); } else { console.error(`Error: ${error}`); }}Configuration
Gateway and Timeout
const tv = new TruthVouch({ apiKey: 'tv_live_...', gatewayUrl: 'https://gateway.truthvouch.com', timeoutMs: 30000, // HTTP timeout maxRetries: 3, // Retry attempts});Circuit Breaker
For production, configure fail mode and circuit breaker:
const tv = new TruthVouch({ apiKey: 'tv_live_...', failMode: 'open', // 'open': bypass on failure, 'closed': raise error circuitBreakerThreshold: 5, // Failures before circuit opens circuitBreakerRecoverySeconds: 60, // Seconds before recovery probe});| failMode | Circuit Open Behavior |
|---|---|
'open' (default) | Bypass gateway, call provider directly (degraded but operational) |
'closed' | Raise GatewayUnreachableError (safe but blocks traffic) |
Environment Variables
Configure SDK behavior via environment variables:
TRUTHVOUCH_API_KEY=tv_live_...TRUTHVOUCH_GATEWAY_URL=https://gateway.truthvouch.comTRUTHVOUCH_TIMEOUT_MS=30000TRUTHVOUCH_FAIL_MODE=openTRUTHVOUCH_MAX_RETRIES=3Load automatically:
const tv = new TruthVouch(); // Reads from env varsReact Integration
Use TruthVouch in React apps with the Vercel AI SDK integration:
import { useChat } from 'ai/react';import TruthVouch from '@truthvouch/sdk';
const tv = new TruthVouch({ apiKey: process.env.NEXT_PUBLIC_TRUTHVOUCH_API_KEY });
export default function ChatComponent() { const { messages, input, handleInputChange, handleSubmit } = useChat({ api: '/api/chat', // Governance is enforced server-side });
return ( <div> {messages.map(m => ( <div key={m.id}>{m.content}</div> ))} <form onSubmit={handleSubmit}> <input value={input} onChange={handleInputChange} /> <button type="submit">Send</button> </form> </div> );}Complete Example
import TruthVouch, { PolicyBlockedError, RateLimitError } from '@truthvouch/sdk';
async function main() { const tv = new TruthVouch({ apiKey: process.env.TRUTHVOUCH_API_KEY, });
try { // OpenAI drop-in const openai = tv.openai(); const completion = await openai.chat.completions.create({ model: 'gpt-4o', messages: [ { role: 'system', content: 'You are a helpful assistant about AI governance.', }, { role: 'user', content: 'What is hallucination in AI?', }, ], temperature: 0.7, max_tokens: 500, });
console.log('Response:', completion.choices[0].message.content); console.log('Verdict:', (completion as any).governance.verdict);
if ((completion as any).governance.alerts?.length > 0) { console.log('Alerts detected:'); (completion as any).governance.alerts.forEach((alert: any) => { console.log(` - ${alert.severity}: ${alert.message}`); }); }
// Manual scan const scanResult = await tv.scan({ prompt: 'Who won the 2024 US Presidential election?', response: 'The 2024 US Presidential election winner was announced in November 2024.', });
console.log(`\nManual scan verdict: ${scanResult.verdict}`); console.log(`Trust score: ${scanResult.trustScore}`); } catch (error) { if (error instanceof PolicyBlockedError) { console.log(`Blocked: ${error.governanceReport.policyId}`); } else if (error instanceof RateLimitError) { console.log(`Rate limited, retry after ${error.retryAfter}s`); } else { console.error(`Error: ${error}`); } }}
main();