Skip to content

JavaScript / Node.js

Obstruo exposes an OpenAI-compatible API, so the official openai npm package works with Obstruo without any changes to your application logic.

Prerequisites

  • An ObstruoKey and endpoint URL - see Quick Start
  • A Logical Model configured in your project
  • Node.js 18 or later

openai npm package

Install the package:

npm install openai

Replace your client instantiation:

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "your-obstruo-key",
  baseURL: "https://api.obstruo.ai/your-org/v1",
});

Everything else stays the same:

const response = await client.chat.completions.create({
  model: "obstruo-chat",
  messages: [
    { role: "system", content: "You are a helpful assistant." },
    { role: "user", content: "Summarise this contract: ..." },
  ],
});

console.log(response.choices[0].message.content);
const stream = await client.chat.completions.create({
  model: "obstruo-chat",
  messages: [{ role: "user", content: "Tell me a story." }],
  stream: true,
});

for await (const chunk of stream) {
  const text = chunk.choices[0]?.delta?.content ?? "";
  process.stdout.write(text);
}

To read the x-obstruo-pii-state header, use fetch directly: the openai SDK does not expose response headers on streaming requests:

const res = await fetch(`${baseURL}/chat/completions`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${apiKey}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "obstruo-chat",
    stream: true,
    messages: [{ role: "user", content: "Hello!" }],
  }),
});

const piiState = res.headers.get("x-obstruo-pii-state");
// "no-pii" | "redacted" | "disabled"
const response = await client.embeddings.create({
  model: "obstruo-embedding",
  input: "The quick brown fox",
});

const vector = response.data[0].embedding;
const tools = [
  {
    type: "function",
    function: {
      name: "get_weather",
      description: "Get weather for a city",
      parameters: {
        type: "object",
        properties: { city: { type: "string" } },
        required: ["city"],
      },
    },
  },
];

const response = await client.chat.completions.create({
  model: "obstruo-chat",
  messages: [{ role: "user", content: "What's the weather in Warsaw?" }],
  tools,
});

Environment variables

export OBSTRUO_API_KEY="your-obstruo-key"
export OBSTRUO_BASE_URL="https://api.obstruo.ai/your-org/v1"
const client = new OpenAI({
  apiKey: process.env.OBSTRUO_API_KEY,
  baseURL: process.env.OBSTRUO_BASE_URL,
});

Reading gateway metadata

Obstruo adds an obstruo key to every non-streaming response with request-level metadata:

const response = await client.chat.completions.create({
  model: "obstruo-chat",
  messages: [{ role: "user", content: "Hello!" }],
});

// standard OpenAI fields
console.log(response.choices[0].message.content);

// gateway metadata
const meta = response.obstruo ?? {};

// routing info
console.log(meta.routing?.resolved_model);  // "gpt-4o-mini"
console.log(meta.routing?.provider_type);   // "OpenAI"

// redaction summary
console.log(meta.redaction?.total_entities); // 0 = no PII found
console.log(meta.redaction?.by_category);    // { EMAIL_ADDRESS: 1, ... }

TypeScript

The openai package ships with TypeScript types. The obstruo metadata key is not part of the official type definitions, so access it via a cast:

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.OBSTRUO_API_KEY!,
  baseURL: process.env.OBSTRUO_BASE_URL!,
});

const response = await client.chat.completions.create({
  model: "obstruo-chat",
  messages: [{ role: "user", content: "Hello!" }],
});

const meta = (response as any).obstruo as {
  routing: {
    resolved_model: string;
    provider_type: string;
    duration_ms: number;
  };
  redaction: {
    total_entities: number;
    by_category: Record<string, number>;
    duration_ms: number;
  };
} | undefined;

Next steps