Main Endpoints
3.1 POST /chat/completions — OpenAI-compatible (recommended)
You can use the official OpenAI SDK directly — just point base_url to your deployer's address.
Request body
{
"messages": [
{"role": "user", "content": "..."}
],
"stream": true, // default true; false for non-streaming
"conversation_id": "conv-xxx" // optional, for continuing a session; omit to create new
}Streaming response (stream=true, identical to OpenAI)
Content-Type: text/event-stream. Each event starts with data: and ends with \n\n:
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1745300000,"model":"...","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1745300000,"model":"...","choices":[{"index":0,"delta":{"content":"Deep"},"finish_reason":null}]}
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1745300000,"model":"...","choices":[{"index":0,"delta":{"content":" learning"},"finish_reason":null}]}
...
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1745300000,"model":"...","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]Non-streaming response (stream=false)
{
"id": "chatcmpl-xxx",
"object": "chat.completion",
"created": 1745300000,
"model": "...",
"choices": [{
"index": 0,
"message": {"role": "assistant", "content": "..."},
"finish_reason": "stop"
}],
"usage": {"prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0},
"conversation_id": "conv-xxx" // ⚠️ non-standard extension field
}3.2 Key differences from the OpenAI standard (must read)
| Field | OpenAI | OpenJellyfish | Behavior |
|---|---|---|---|
messages | Full history | Only the last role="user" message | History is maintained server-side via conversation_id — don't rely on client-sent history |
conversation_id | ❌ | ✅ extension field | Omit → new session; include → continue session |
model | Selects model | Ignored | Model is bound at service creation — client value has no effect |
temperature / top_p / max_tokens / stop / presence_penalty etc. | Affect generation | Ignored | Same — fixed at service level |
tools / tool_choice / function_call / response_format / logprobs / seed | Supported | Not supported | Service may call tools internally, but not exposed to consumers |
usage field | Real token counts | All 0 | OpenAI-compatible endpoint doesn't return real tokens yet; check Settings → Usage in the admin UI for LLM usage |
Multimodal image_url | Supported | Not supported (use /chat) | See §3.3 |
In short: treat
messagesas "send only this turn's user message" and letconversation_idmanage context.
3.3 POST /chat — Custom SSE (multimodal, rich events)
Use this endpoint if you need image input, or want to receive thinking / tool / subagent events for a richer UI.
Request body
{
"conversation_id": "conv-xxx",
"message": "..." // string or OpenAI multimodal content blocks array
}Multimodal example:
{
"conversation_id": "conv-xxx",
"message": [
{"type": "text", "text": "What's in this image?"},
{"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,/9j/4AA..."}}
]
}Response
Content-Type: text/event-stream. Note: not the standard SSE event: <type> + data: <json> two-line format — only data: lines are sent, with the event type in the JSON body's type field:
data: {"type": "thinking", "content": "The user wants me to..."}
data: {"type": "tool_call", "name": "web_search", "args": {"query": "..."}}
data: {"type": "tool_call_chunk", "args_delta": "..."}
data: {"type": "tool_result", "name": "web_search", "content": "..."}
data: {"type": "token", "content": "Deep"}
data: {"type": "token", "content": " learning"}
data: {"type": "done"}type | Fields | Description |
|---|---|---|
thinking | content | Model reasoning / chain-of-thought delta (thinking models only) |
tool_call | name, args | Agent decides to call a tool |
tool_call_chunk | args_delta | Streaming tool argument delta (when model outputs args in chunks) |
tool_result | name, content | Tool return value (truncated to 500 chars) |
token | content | Final answer token delta (concatenate for full response) |
done | — | Normal completion |
error | content | Error during streaming; no done follows |
No
[DONE]terminator (that's only for §3.1 OpenAI-compatible). Custom SSE uses{"type": "done"}to signal end.For basic chat integration, §3.1 OpenAI-compatible endpoint is enough.
/chatis for UIs that need to show the agent's thinking process.
3.4 Conversation management
| Path | Method | Purpose |
|---|---|---|
/conversations | POST | Explicitly create a conversation (usually unnecessary — /chat/completions auto-creates) |
/conversations/{conv_id} | GET | Fetch full conversation history |
/conversations/{conv_id}/files | GET | List files generated by the Agent in this conversation |
/conversations/{conv_id}/files/{path} | GET | Download generated files (images, docs, etc.); supports ?token= for <img src> auth |
/conversations/{conv_id}/media-token | GET | Get a short-lived media access token (for standalone chat pages) |
POST /conversations request / response
// Request body (title optional)
{ "title": "Customer inquiry #123" }
// Response
{
"id": "conv-xxxxxxxxxxxx",
"title": "Customer inquiry #123",
"created_at": "2026-04-22T...",
"updated_at": "2026-04-22T..."
}GET /conversations/{conv_id} response
{
"id": "conv-xxx",
"title": "...",
"created_at": "...",
"updated_at": "...",
"messages": [
{"role": "user", "content": "...", "created_at": "..."},
{"role": "assistant", "content": "...", "created_at": "..."}
// ...
]
}Non-existent or service-Key-mismatched
conv_id→404 {"detail": "Conversation not found"}.