Skip to content

JavaScript and TypeScript

The OpenAI and Anthropic Node SDKs, LangChain.js and the Vercel AI SDK pointed at the gateway, with streaming and refusal handling.

Updated 02 Nov 2026Checked against ai-firewall@339de55, cli@4c8c3b7

The examples are ES modules (top-level await): save them as .mjs or .ts and run with Node 20 or later. Each reads VULNETIX_API_KEY and VULNETIX_ORG_ID.

vulnetix ai-firewall snippet --lang ts --sdk openai --provider openai
vulnetix ai-firewall snippet --lang ts --sdk anthropic
vulnetix ai-firewall snippet --lang ts --sdk vercel-ai --provider openai

openai-node reads OPENAI_BASE_URL, so install shell routes it without code changes. The Vercel AI SDK does not read it.

OpenAI SDK

npm install openai
import OpenAI from 'openai'

const client = new OpenAI({
  baseURL: `https://guardrails.vulnetix.com/openai/${process.env.VULNETIX_ORG_ID}/v1`,
  apiKey: process.env.VULNETIX_API_KEY, // the Vulnetix key, not an OpenAI key
})

const response = await client.chat.completions.create({
  model: 'gpt-4o-mini',
  messages: [{ role: 'user', content: 'Hello' }],
})
console.log(response.choices[0].message.content)

Streaming:

const stream = await client.chat.completions.create({
  model: 'gpt-4o-mini',
  messages: [{ role: 'user', content: 'Hello' }],
  stream: true,
})
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? '')
}

Refusals:

try {
  await client.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [{ role: 'user', content: 'Hello' }],
  })
} catch (err) {
  if (err instanceof OpenAI.PermissionDeniedError) {
    // err.error is the body's `error` object: code, blocked_by (a string), violations
    const detail = err.error as { code?: string; blocked_by?: string } | undefined
    console.error(`refused: ${detail?.code} (rule: ${detail?.blocked_by ?? 'n/a'})`)
  }
  throw err
}

Anthropic SDK

npm install @anthropic-ai/sdk
import Anthropic from '@anthropic-ai/sdk'

const client = new Anthropic({
  baseURL: `https://guardrails.vulnetix.com/anthropic/${process.env.VULNETIX_ORG_ID}`, // no /v1
  authToken: process.env.VULNETIX_API_KEY,
})

const message = await client.messages.create({
  model: 'claude-sonnet-4-5',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'Hello' }],
})
console.log(message.content)

authToken sends Authorization: Bearer and apiKey sends x-api-key; the gateway accepts either. Stream with client.messages.stream({...}).on('text', t => process.stdout.write(t)). Refusals throw Anthropic.PermissionDeniedError.

Vercel AI SDK

npm install ai @ai-sdk/openai
import { createOpenAI } from '@ai-sdk/openai'
import { generateText, streamText, APICallError } from 'ai'

const vulnetix = createOpenAI({
  baseURL: `https://guardrails.vulnetix.com/openai/${process.env.VULNETIX_ORG_ID}/v1`,
  apiKey: process.env.VULNETIX_API_KEY!,
})

try {
  const { text } = await generateText({ model: vulnetix('gpt-4o-mini'), prompt: 'Hello' })
  console.log(text)
} catch (err) {
  if (APICallError.isInstance(err) && err.statusCode === 403) {
    const body = JSON.parse(err.responseBody ?? '{}')
    console.error(`refused: ${body.error?.code} (rule: ${body.error?.blocked_by ?? 'n/a'})`)
  }
  throw err
}

const result = streamText({ model: vulnetix('gpt-4o-mini'), prompt: 'Hello' })
for await (const delta of result.textStream) process.stdout.write(delta)

Recent versions of @ai-sdk/openai call the Responses API by default. That works against openai, which serves responses. For any other provider use vulnetix.chat('model') so the request goes to /v1/chat/completions.

LangChain.js

npm install @langchain/openai
import { ChatOpenAI } from '@langchain/openai'

const llm = new ChatOpenAI({
  apiKey: process.env.VULNETIX_API_KEY,
  model: 'gpt-4o-mini',
  configuration: {
    baseURL: `https://guardrails.vulnetix.com/openai/${process.env.VULNETIX_ORG_ID}/v1`,
  },
})
console.log((await llm.invoke('Hello')).content)

Error codes: see Python, Codes to handle and Errors.

Edit this pageSources: cli/pkg/aifirewall/templates/ts-openai.tmpl, cli/pkg/aifirewall/templates/ts-anthropic.tmpl, cli/pkg/aifirewall/templates/ts-vercel-ai.tmpl, cli/pkg/aifirewall/snippet.go, ai-firewall/internal/api/codec.go, ai-firewall/internal/policy/engine.go, ai-firewall/website/content/docs/sdks/nodejs-typescript.md, ai-firewall/website/content/docs/sdks/anthropic-typescript.md, ai-firewall/website/content/docs/sdks/vercel-ai-sdk.md, ai-firewall/website/content/docs/sdks/langchain.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.