Node.js / TypeScript Integration
Native fetch-based integration for Node.js 18+ and all modern JavaScript environments. Fully typed.
Basic Fetch (No Dependencies)
typescript
const GUARDRAIL_API_KEY = process.env.GUARDRAIL_API_KEY!;
interface GuardrailResult {
risk_score: number;
status: 'approved' | 'flagged' | 'rejected';
flags: string[];
redacted_text: string;
}
async function checkAgentOutput(agentId: string, proposedText: string): Promise<GuardrailResult> {
const response = await fetch('https://api.guardrail.ai/v1/guardrail/check', {
method: 'POST',
headers: {
'Authorization': `Bearer ${GUARDRAIL_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ agent_id: agentId, proposed_text: proposedText }),
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Guardrail error ${response.status}: ${error.detail}`);
}
return response.json() as Promise<GuardrailResult>;
}
// Usage
const result = await checkAgentOutput('support-bot', 'Your card number 4111... was processed.');
if (result.status === 'approved') {
console.log('Safe:', result.redacted_text);
} else {
console.warn('Blocked:', result.flags);
}Express.js Middleware
Add Guardrail as Express middleware to automatically screen all AI output routes.
typescript (express)
import express, { Request, Response, NextFunction } from 'express';
const GUARDRAIL_KEY = process.env.GUARDRAIL_API_KEY!;
// Middleware factory
function guardrailMiddleware(agentId: string) {
return async (req: Request, res: Response, next: NextFunction) => {
const textToCheck = req.body?.ai_response;
if (!textToCheck) return next();
try {
const result = await fetch('https://api.guardrail.ai/v1/guardrail/check', {
method: 'POST',
headers: { 'Authorization': `Bearer ${GUARDRAIL_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ agent_id: agentId, proposed_text: textToCheck }),
}).then(r => r.json());
if (result.status === 'rejected') {
return res.status(400).json({ error: 'AI response blocked by safety policy', flags: result.flags });
}
// Replace with safe redacted version
req.body.ai_response = result.redacted_text;
req.body.guardrail_risk_score = result.risk_score;
next();
} catch (err) {
console.error('Guardrail check failed:', err);
next(); // Fail-open: proceed without blocking on guardrail errors
}
};
}
// Apply to your routes
const app = express();
app.post('/api/chat', guardrailMiddleware('chat-agent'), async (req, res) => {
// By the time we're here, req.body.ai_response is already sanitized
res.json({ message: req.body.ai_response });
});Vercel AI SDK Integration
typescript (vercel ai)
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
export async function POST(req: Request) {
const { messages } = await req.json();
// 1. Generate LLM response
const result = streamText({ model: openai('gpt-4o'), messages });
const fullText = await result.text;
// 2. Run through Guardrail before returning
const guardrail = await fetch('https://api.guardrail.ai/v1/guardrail/check', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.GUARDRAIL_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ agent_id: 'vercel-ai-chat', proposed_text: fullText }),
}).then(r => r.json());
if (guardrail.status === 'rejected') {
return Response.json({ role: 'assistant', content: 'I cannot provide that information.' });
}
return Response.json({ role: 'assistant', content: guardrail.redacted_text });
}