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.
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.
Base URL
Set this as your client's base_url / baseURL. All standard OpenAI paths hang off it: /chat/completions, /embeddings, and /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.
The unfiltered catalog — includes embeddings-only and other non-chat aliases that /v1/models leaves out of the picker.
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 = 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
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.
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
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
Use nomic-embed-text for semantic search, clustering, and retrieval. Batch inputs are supported and — like everything else — included in your seat.
Image generation
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.
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.
/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
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.
Lists the voices available for a given model query parameter — a discovery extension beyond the core OpenAI API, useful for populating a voice picker.
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.