OpenAI-Compatible Endpoint
Ragz speaks the OpenAI Chat Completions wire format, so any tool, SDK, or agent framework that already talks to OpenAI can talk to Ragz instead — point the base URL at your Ragz instance and use a Ragz API key. Every call still runs Ragz's real RAG pipeline (retrieval, ACL enforcement, citations, no-answer mode) — this is not a passthrough to an upstream LLM.
Base URL & authentication
All routes below require an API key
issued by a superadmin, scoped to one user and one workspace. Send it as a
bearer token (or X-API-Key header) — never a /api/v1 session JWT.
| Environment | Base URL |
|---|---|
| Self-hosted (example) | https://ragz.example.com/external/v1 |
| Local | http://127.0.0.1:8000/external/v1 |
Authorization: Bearer $RAGZ_API_KEY
# or
X-API-Key: $RAGZ_API_KEYChat Completions
OpenAI-compatible chat completion. Runs the full Ragz RAG pipeline and returns
a standard chat-completion object, extended with an x_ragz object.
POST /external/v1/openai/chat/completions · Auth: API key
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
messages | array | Yes | OpenAI-style message list. Only the last role: "user" message is used as the question — Ragz keeps its own server-side conversation state rather than replaying client history. Max 500 messages. |
model | string | No | Accepted for compatibility; the workspace's configured model is authoritative. |
stream | boolean | No | Streaming is not supported yet — always returns a complete JSON response. Default false. |
Unrecognized OpenAI fields (temperature, top_p, tools, …) are accepted
and silently ignored.
Sample request
curl -sX POST https://ragz.example.com/external/v1/openai/chat/completions \
-H "Authorization: Bearer $RAGZ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "ragz",
"messages": [
{"role": "user", "content": "What is our refund policy?"}
]
}'Sample response
{
"id": "chatcmpl-9f2c1e...",
"object": "chat.completion",
"created": 1755200000,
"model": "ragz",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Enterprise customers may request a refund within 30 days..."
},
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0 },
"x_ragz": {
"citations": [
{ "marker": 1, "document_id": "...", "chunk_ref": "...", "page": 4, "score": 0.87,
"section": "Refunds", "version": 2, "url": null }
],
"grounding": "documents",
"no_answer": false,
"conversation_id": "c3d4...-uuid"
}
}Response fields
| Field | Type | Description |
|---|---|---|
id | string | Chat-completion id. |
object | string | Always chat.completion. |
created | integer | Unix timestamp (seconds). |
model | string | The model that answered. |
choices[].message.content | string | The answer text. |
choices[].finish_reason | string | Completion reason, e.g. stop. |
usage | object | Token counts — not populated (all zeros). Use /reports/usage for real accounting. |
x_ragz.citations | array | Ragz citations — see fields below. |
x_ragz.grounding | string | Grounding source, e.g. documents, web. |
x_ragz.no_answer | boolean | true when retrieval lacked sufficient grounding. |
x_ragz.conversation_id | string (uuid) | The conversation Ragz created or continued. |
Using the openai Python SDK
Point the SDK's base_url at Ragz's external OpenAI root and pass your Ragz
key — no other change needed:
from openai import OpenAI
client = OpenAI(
api_key="rgz_live_...", # your Ragz API key
base_url="https://ragz.example.com/external/v1/openai",
)
resp = client.chat.completions.create(
model="ragz",
messages=[{"role": "user", "content": "What is our refund policy?"}],
)
print(resp.choices[0].message.content)
print(resp.model_extra.get("x_ragz")) # citations, grounding, no_answerNative Chat
The Ragz-native equivalent: plain {question, conversation_id} in, structured
citations out — no OpenAI envelope.
POST /external/v1/chat · Auth: API key
Request body
| Parameter | Type | Required | Description |
|---|---|---|---|
question | string | Yes | The question to answer. 1–32000 characters. |
conversation_id | string (uuid) | No | Continue an existing conversation owned by the key's user and workspace. Omit to start a new one. |
Sample request
curl -sX POST https://ragz.example.com/external/v1/chat \
-H "Authorization: Bearer $RAGZ_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "question": "What is our refund policy?" }'Sample response
{
"answer": "Enterprise customers may request a refund within 30 days...",
"citations": [
{ "marker": 1, "document_id": "...", "chunk_ref": "...", "page": 4, "score": 0.87,
"section": "Refunds", "version": 2, "url": null }
],
"no_answer": false,
"grounding": "documents",
"conversation_id": "c3d4...-uuid"
}Response fields
| Field | Type | Description |
|---|---|---|
answer | string | The grounded answer text. |
citations | array | Supporting citations — see fields below. |
no_answer | boolean | true when retrieval lacked sufficient grounding. |
grounding | string | Grounding source, e.g. documents, web. |
conversation_id | string (uuid) | The conversation Ragz created or continued. |
Citation fields
Each entry in citations (and x_ragz.citations) has this shape:
| Field | Type | Description |
|---|---|---|
marker | integer | The [n] marker referenced in the answer text. |
document_id | string (uuid) | null | Source document id (null for web citations). |
chunk_ref | string | Internal reference to the cited chunk. |
page | integer | Page number in the source document. |
score | number | Retrieval relevance score. |
section | string | null | Section/heading the chunk came from. |
version | integer | Document version the citation is from. |
url | string | null | Source URL (populated for web citations). |
List Models
Returns the OpenAI models.list shape, scoped to the key: it always lists
exactly the one chat model configured as the key's workspace default (a key
can't discover or switch to a model outside its workspace).
GET /external/v1/openai/models · Auth: API key
Sample request
curl -s https://ragz.example.com/external/v1/openai/models \
-H "Authorization: Bearer $RAGZ_API_KEY"Sample response
{ "object": "list", "data": [{ "id": "gpt-4o-mini", "object": "model", "owned_by": "ragz" }] }Response fields
| Field | Type | Description |
|---|---|---|
object | string | Always list. |
data[].id | string | The workspace's configured chat model id. |
data[].object | string | Always model. |
data[].owned_by | string | Always ragz. |
Notes
- Not a passthrough. Every call runs Ragz's retrieval, ACL enforcement, citations, and no-answer mode — the OpenAI shape is the wire format only.
- Rate limited. Both
/external/v1/chatand/external/v1/openai/chat/completionsshare the same per-key-user rate limit as interactive chat. A429means back off and retry. - Workspace-scoped. A key can only ever see the one workspace it was
issued for — passing another workspace's
conversation_idreturns404.
Why this matters
This is the fastest way to bolt Ragz's grounded, cited answers into existing
tooling — LangChain, LlamaIndex, custom agents, internal Slack bots, anything
already wired for an OpenAI-shaped base_url — with no bespoke integration.