Skip to main content

Node.js Integration

Use the OpenAI Node client with the documented Keeptrusts Chat Completions route and a client API token. Keep the client in a trusted server runtime; do not expose the token in browser code or infer support for an unlisted OpenAI route.

Prerequisites

  • Complete the Quickstart and keep the gateway running.

  • Create a client API token for the application.

  • Install the client:

    npm install openai

Set the connection values in the server environment:

export KEEPTRUSTS_GATEWAY_URL="http://127.0.0.1:41002/v1"
export KEEPTRUSTS_REQUEST_TOKEN="kt_..."
export KEEPTRUSTS_MODEL="gpt-5.4-mini"

Send a chat request

import OpenAI from "openai";

function requiredEnv(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`${name} is required`);
return value;
}

const model = requiredEnv("KEEPTRUSTS_MODEL");
const client = new OpenAI({
baseURL: requiredEnv("KEEPTRUSTS_GATEWAY_URL"),
apiKey: requiredEnv("KEEPTRUSTS_REQUEST_TOKEN"),
});

const response = await client.chat.completions.create({
model,
messages: [
{ role: "user", content: "Summarize this incident report." },
],
});

console.log(response.choices[0]?.message.content);

The model name must be exposed by the gateway. Setting the environment variable does not create an upstream provider target.

Stream a response

const stream = await client.chat.completions.create({
model,
messages: [{ role: "user", content: "Explain this change." }],
stream: true,
});

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

Input policies run before the upstream request. Policies that require the complete output can buffer streaming responses, so validate latency with the actual chain. See Streaming and SSE.

Use the client in a server route

Create one server-side client and inject it into the handlers that need model access. Never serialize the token into HTML, a client bundle, or a public runtime environment variable.

export async function summarize(input: string): Promise<string> {
const response = await client.chat.completions.create({
model,
messages: [{ role: "user", content: input }],
});

return response.choices[0]?.message.content ?? "";
}

Handle gateway decisions

try {
await summarize("Review this text.");
} catch (error) {
if (error instanceof OpenAI.APIError) {
if (error.status === 400 && error.code === "content_policy_violation") {
console.error("Blocked by policy");
} else if (error.status === 401 || error.status === 403) {
console.error("Client token rejected");
} else if (error.status === 429) {
console.error("Rate limited");
} else {
throw error;
}
} else {
throw error;
}
}

Do not blindly retry a model request. A timeout does not prove that the upstream call failed before it incurred usage.

Verify the governed path

curl -fsS \
-H "Authorization: Bearer ${KEEPTRUSTS_REQUEST_TOKEN}" \
"${KEEPTRUSTS_GATEWAY_URL}/models"

kt events tail --since 10m --follow

Send a representative request while the event tail is active. The matching event is the proof that the Node.js process used Keeptrusts.

Next steps