OpenAI-compatible endpoint
Point an existing OpenAI SDK integration at POST /v1/chat/completions and get grounded, cited answers with no code changes.
POST /v1/chat/completions is a drop-in for any framework that already
speaks the OpenAI chat-completions wire format — same request/response
shape, so a stock OpenAI SDK works against it with just a base URL and key
change.
Point your SDK at it
from openai import OpenAI
client = OpenAI(
base_url="https://apibr.aize.dev/v1",
api_key="bzk_...", # your Braize API key
)
response = client.chat.completions.create(
model="chat-default",
messages=[{"role": "user", "content": "What is our refund policy?"}],
)
print(response.choices[0].message.content)Any OpenAI-compatible client library works the same way — change the base URL and the key, nothing else.
What's really happening
Underneath, this is a thin adapter over the exact same pipeline as
POST /v1/query: same retrieval, same ACL pre-filter, same grounding, same
metering, same request logs. It's stateless like OpenAI's API — you resend
the message history on every call — and each call opens a fresh Braize
conversation (its id rides in the braize extension field below).
Fields your SDK sends that Braize doesn't use for anything — n, tools,
max_tokens, and friends — are accepted and silently ignored, so existing
call sites don't need to be stripped down first.
The one deliberate contract difference
This is the one Braize endpoint that does not use the {data, meta}
envelope or RFC 9457 errors — on purpose, because its entire reason to exist
is byte-for-byte OpenAI wire compatibility. Wrapping either would break
every stock OpenAI SDK that talks to it. Every other Braize-native endpoint
keeps the envelope + Problem rules unchanged; this compatibility surface is
the one named exception.
- Errors come back as OpenAI-shaped error objects
(
{"error": {"message", "type", "code", "param"}}), not RFC 9457 Problems. - Value-add rides in one additive field,
braize, on the response — standard SDKs ignore fields they don't recognize; Braize-aware clients can read it:
{
"id": "chatcmpl-…",
"object": "chat.completion",
"created": 1735689600,
"model": "chat-default",
"choices": [{ "index": 0, "message": { "role": "assistant", "content": "…" }, "finish_reason": "stop" }],
"usage": { "prompt_tokens": 42, "completion_tokens": 118, "total_tokens": 160 },
"braize": {
"conversation_id": "…",
"grounded": true,
"groundedness": 0.94,
"confidence": 0.92,
"is_fallback": false,
"citations": [{ "type": "citation", "document_id": "…", "title": "Refund Policy" }]
}
}A knowledge-base miss is not an error — content carries Braize's
honest fallback message, finish_reason: "stop", braize.is_fallback: true,
and empty citations. A genuine mid-stream failure surfaces as
braize.error (a Problem object) on the final chunk, then data: [DONE].
Streaming
With "stream": true, the response is text/event-stream in OpenAI's
data-only framing (no event: names) — every frame's data: payload is a
ChatCompletionChunk; the final chunk carries finish_reason, usage, and
braize; the stream ends with data: [DONE].
The Braize extension on the request side too
answer_mode (fast | balanced | thorough) works exactly like
/v1/query's field — pass it via your SDK's extra_body if it doesn't
expose custom fields directly. An explicit temperature still overrides the
mode's preset.
What's next
- Asking questions & streaming — the native endpoint this adapts, with the full field reference.
- Full schema: API reference.