cURL / fetch against OpenAI-compatible HTTP

Set GATEWAY_V1_ROOT to the API root including /v1 (typical @routerbrain/sdk serverURL shape), e.g. http://127.0.0.1:8080/v1; GATEWAY_API_KEY is the tenant API key. Full fields, error codes, and limits: HTTP service README shipped with your deployment.

export GATEWAY_V1_ROOT="http://api.routerbrain.ai/v1"
export GATEWAY_API_KEY="sk-…"

Health check (no key)

curl -sS "$GATEWAY_V1_ROOT/ping"

Minimal non-streaming Chat

curl -sS "$GATEWAY_V1_ROOT/chat/completions" \
  -H "Authorization: Bearer $GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o-mini",
    "messages": [{ "role": "user", "content": "ping" }]
  }'

Streaming (SSE)

Add "stream": true to JSON. Response Content-Type: text/event-stream, body is data: {…} JSON lines, usually ending with data: [DONE]. Use curl -N to see live output:

curl -N -sS "$GATEWAY_V1_ROOT/chat/completions" \
  -H "Authorization: Bearer $GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{
    "model": "openai/gpt-4o-mini",
    "messages": [{ "role": "user", "content": "Explain SSE in two sentences." }],
    "stream": true
  }'

Parsers must split data: lines per SSE; mid-stream data: payloads may represent errors—same idea as GatewaySseErrorSDK error types.

Browser fetch (non-streaming sketch)

const r = await fetch(`${import.meta.env.VITE_GATEWAY_BASE}/v1/chat/completions`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${import.meta.env.VITE_GATEWAY_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "openai/gpt-4o-mini",
    messages: [{ role: "user", content: "ping" }],
  }),
});
const json = await r.json();
if (!r.ok) throw new Error(JSON.stringify(json));

Streaming fetch + ReadableStream needs a custom SSE parser; production often uses a Node proxy or @routerbrain/sdk.

Official OpenAI SDKs (custom base URL)

If the SDK supports baseURL and apiKey:

  • baseURL…/v1 (or whatever that SDK expects with /v1);
  • apiKey → tenant key.

This service differs from “raw upstream OpenAI” for input_file, pdf_preprocess, etc.—Chat Completions.

Python (openai)

Names depend on your installed version:

from openai import OpenAI

client = OpenAI(
    base_url="http://127.0.0.1:8080/v1",
    api_key="sk-…",
)

resp = client.chat.completions.create(
    model="openai/gpt-4o-mini",
    messages=[{"role": "user", "content": "ping"}],
)
print(resp.choices[0].message.content)

Streaming (iterate chunk per current docs):

stream = client.chat.completions.create(
    model="openai/gpt-4o-mini",
    messages=[{"role": "user", "content": "Explain SSE in two sentences."}],
    stream=True,
)
for chunk in stream:
    piece = chunk.choices[0].delta.content or ""
    if piece:
        print(piece, end="", flush=True)
print()

TypeScript / Node (openai on npm)

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "http://127.0.0.1:8080/v1",
  apiKey: "sk-…",
});

const resp = await client.chat.completions.create({
  model: "openai/gpt-4o-mini",
  messages: [{ role: "user", content: "ping" }],
});

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

Streaming:

const stream = await client.chat.completions.create({
  model: "openai/gpt-4o-mini",
  messages: [{ role: "user", content: "Explain SSE in two sentences." }],
  stream: true,
});

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

Install: pip install openai, pnpm add openai (versions per upstream docs).

See also

Back to docs home