OpenAI-Compatible API
POST /chat/completions mimics the OpenAI Chat Completions response envelope closely enough that OpenAI-SDK clients can parse the reply, but it is not a full drop-in replacement — read the "What this endpoint actually does" section before wiring anything demo-critical to it.
Endpoint
| Method | Path | Action | Description |
|---|---|---|---|
| POST | /chat/completions | AgentSendMessage | OpenAI-shaped chat completion, backed by the first available agent |
AgentSendMessage is admin/operator/developer/service.
What this endpoint actually does (read before demoing)
The handler (chat_completions, crates/surfaces/hoziron-api/src/routes.rs) does the following, and nothing more:
- Reads the request body as
{model, messages, stream}—streamis parsed but ignored (no SSE/streaming support; the response is always a single non-streamed JSON body regardless of"stream": true). - Scans
messagesfrom the end for the last entry with"role": "user"and takes itscontentas the entire prompt. System messages, prior assistant turns, and multi-turn history are all discarded — only the single most recent user message is used. modelis not used to select a provider or route anything. The value you send is echoed back in the response'smodelfield (or"hoziron-default"if omitted), but it has no effect on which model actually answers.- Picks the first agent returned by
list_agents()— whichever agent that happens to be — and calls the same internalsend_messagepath asPOST /agents/{id}/send. There is no way to target a specific agent through this endpoint. - Returns
503if no agents exist at all,400if no user message was found.
If you need real agent targeting, multi-turn history, or streaming, use POST /agents/{id}/invoke or POST /agents/{id}/send instead — this endpoint exists for point compatibility with tools that only speak the OpenAI wire format, not as the recommended integration path.
POST /chat/completions
curl -X POST -H "Api-Version: v1" -H "Authorization: Bearer hzn_sk_..." \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of France?"}
]
}' \
http://localhost:4200/chat/completions
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
model | string | No | Echoed back verbatim; does not select a provider/model |
messages | array | Yes | Only the last role: "user" message is used |
stream | boolean | No | Accepted, parsed, and ignored — always returns a full non-streamed response |
There is no temperature/max_tokens field in the parsed request struct — sending them is harmless (extra JSON fields are ignored), but they have no effect.
Response (200)
{
"id": "chatcmpl-a1b2c3d4-...",
"object": "chat.completion",
"created": 1717488000,
"model": "hoziron-default",
"choices": [
{
"index": 0,
"message": {"role": "assistant", "content": "The capital of France is Paris."},
"finish_reason": "stop"
}
],
"usage": {"prompt_tokens": 12, "completion_tokens": 8, "total_tokens": 20}
}
usage.prompt_tokens/completion_tokens are tokens_used / 2 each (an even split of the real total, not independently measured — there is no separate prompt/completion token count on the underlying AgentResponse).
Error (400 — no user message)
{"error": {"message": "No user message provided", "type": "invalid_request_error"}}
Error (503 — no agents provisioned)
{"error": {"message": "No agents available", "type": "server_error"}}
Note these two error shapes use OpenAI's own {"error": {"message", "type"}} envelope, not the platform's usual {"error": {"category", "message"}} envelope — this endpoint is intentionally OpenAI-wire-compatible even in its error responses.
Use with OpenAI SDK
Works for simple single-turn prompts against whichever agent happens to be first in the list — verify that's an acceptable demo posture before relying on it.
Python
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:4200",
api_key="hzn_sk_a1b2c3d4..." # or any non-empty string if auth is disabled
)
response = client.chat.completions.create(
model="ignored",
messages=[{"role": "user", "content": "Summarize our claims process."}]
)
print(response.choices[0].message.content)
curl
curl -H "Api-Version: v1" http://localhost:4200/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer hzn_sk_..." \
-d '{"messages": [{"role": "user", "content": "Hello!"}]}'
Related
- agents.md — the real, fully-featured invocation surface (
/agents/{id}/send,/agents/{id}/invoke) - health-status.md —
/providers,/models(the actual model inventory this endpoint does not let you select from)