OpenAI-compatible. Switch with one base URL.

Developer docs

If you've called an OpenAI-style API before, you already know this one. Here's everything you need to be running in five minutes.

Quickstart

Denizen Blu speaks the OpenAI Chat Completions protocol. Point your existing client at our base URL, drop in your key, and choose any catalog model — like llama-3.3-70b-instruct or deepseek-r1-70b. That's the whole migration.

Python
Node.js
cURL
from openai import OpenAI

client = OpenAI(
    base_url="https://bluroute.denizenblu.com/v1",
    api_key="db-your-key",
)

resp = client.chat.completions.create(
    model="llama-3.3-70b-instruct",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(resp.choices[0].message.content)
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://bluroute.denizenblu.com/v1",
  apiKey: "db-your-key",
});

const resp = await client.chat.completions.create({
  model: "llama-3.3-70b-instruct",
  messages: [{ role: "user", content: "Hello!" }],
});
console.log(resp.choices[0].message.content);
curl https://bluroute.denizenblu.com/v1/chat/completions \
  -H "Authorization: Bearer db-your-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llama-3.3-70b-instruct",
    "messages": [{"role":"user","content":"Hello!"}]
  }'

Authentication

Every request is authenticated with a bearer token in the Authorization header. Create per-seat keys from your dashboard; each key is tied to a seat so usage visibility stays clean.

Tip: Keys are scoped to a seat, not a shared pool. Rotate them freely — revoking one never breaks another teammate's access.

Base URL

BASE https://bluroute.denizenblu.com/v1

Set this as your client's base_url / baseURL. All standard OpenAI paths hang off it: /chat/completions, /embeddings, and /models.

GET /v1/models

Lists every chat- and image-capable model available to your seat: the full open catalog (Llama, DeepSeek, Qwen, Mistral, and more) — all included. Pass any returned ID as the model field; the API is identical for every model.

GET /v1/models/all

The unfiltered catalog — includes embeddings-only and other non-chat aliases that /v1/models leaves out of the picker.

Chat completions

POST /v1/chat/completions

The core endpoint. Accepts the usual fields — model, messages, temperature, max_tokens, top_p, stop, and stream. Responses match the OpenAI schema field-for-field, so your existing parsing code works unchanged.

Streaming

Set stream: true to receive server-sent events as tokens are generated. Because inference is unmetered, streaming long responses costs you nothing extra — stream everything.

stream.py
stream = client.chat.completions.create(
    model="qwen3-32b",
    messages=[{"role": "user", "content": "Write a story."}],
    stream=True,
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")

Function calling

Pass a tools array of JSON-schema function definitions. The model returns a tool_calls payload you can execute and feed back — identical to the OpenAI flow. Support varies by model; check the tools capability flag returned by /v1/models before relying on it.

Responses API

POST /v1/responses

OpenAI's newer Responses API, translated to and from our chat backend under the hood. Takes model, input (a string or a list of input items), plus instructions, temperature, top_p, max_output_tokens, tools, tool_choice, metadata, and user. The response comes back in Responses-object shape, not a chat-completion object.

Note: stream isn't supported on this route yet — a request with stream: true is rejected with a 400 rather than silently returned as a single completed response. If your app needs tokens as they're generated, use /v1/chat/completions instead: it streams today, and everything else about this route — models, tools, the same backend — works identically there.

Legacy completions

POST /v1/completions

The original OpenAI text-completion shape (prompt in, choices[].text out) — kept for older clients and IDE autocomplete integrations that still default to it, including fill-in-the-middle via suffix. New integrations should use /v1/chat/completions.

Embeddings

POST /v1/embeddings

Use nomic-embed-text for semantic search, clustering, and retrieval. Batch inputs are supported and — like everything else — included in your seat.

Image generation

POST /v1/images/generations

Standard OpenAI image-generation shape — model, prompt, optional n (up to 10), size, and response_format (url or b64_json). Prompts are checked against moderation before dispatch, so a rejected prompt never reaches a backend or counts against your seat.

GET /v1/images/{image_id}

Fetches a previously generated image by its id — this is the URL returned in a response_format: "url" result. It's intentionally unauthenticated (a plain <img src> tag can't send an API key); the opaque, high-entropy id is what protects it.

Tip: image-generation models also work directly through /v1/chat/completions — send a normal chat message with an image-capable model and the gateway shims it into a generation call for you.

Audio

POST /v1/audio/speech

Text-to-speech. Takes model, input text, voice (defaults to af_bella), optional response_format (mp3, opus, aac, flac, wav, or pcm), and speed (0.25–4.0). Returns raw audio bytes.

GET /v1/audio/voices

Lists the voices available for a given model query parameter — a discovery extension beyond the core OpenAI API, useful for populating a voice picker.

POST /v1/audio/transcriptions

Speech-to-text. Multipart form upload — file (the audio) and model are required; optional fields are language, prompt, temperature, and response_format (json, text, srt, verbose_json, or vtt).

Migrating in

Most teams migrate in three edits: change the base URL, swap the API key, and set the model string to whichever model you choose — often the open model you already run elsewhere, so outputs stay identical. Streaming, function calling, JSON mode, and stop sequences all behave the same. If something in your OpenAI code doesn't map cleanly, it's a bug on our side — tell us.

Rate & fair use

There is no per-token billing and no hard monthly cap. Concurrency limits protect service quality; enterprise plans raise them. Usage far above the published Fair Use Benchmark may see reduced scheduling priority at peak — never a charge, never a cutoff.

Ready? Grab a key from your dashboard and you'll be streaming tokens in minutes. Start your trial →