Service API Integration · 04

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

jsonc
{
  "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:

text
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)

jsonc
{
  "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)

FieldOpenAIOpenJellyfishBehavior
messagesFull historyOnly the last role="user" messageHistory is maintained server-side via conversation_id — don't rely on client-sent history
conversation_id✅ extension fieldOmit → new session; include → continue session
modelSelects modelIgnoredModel is bound at service creation — client value has no effect
temperature / top_p / max_tokens / stop / presence_penalty etc.Affect generationIgnoredSame — fixed at service level
tools / tool_choice / function_call / response_format / logprobs / seedSupportedNot supportedService may call tools internally, but not exposed to consumers
usage fieldReal token countsAll 0OpenAI-compatible endpoint doesn't return real tokens yet; check Settings → Usage in the admin UI for LLM usage
Multimodal image_urlSupportedNot supported (use /chat)See §3.3

In short: treat messages as "send only this turn's user message" and let conversation_id manage 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

jsonc
{
  "conversation_id": "conv-xxx",
  "message": "..."     // string or OpenAI multimodal content blocks array
}

Multimodal example:

jsonc
{
  "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:

text
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"}
typeFieldsDescription
thinkingcontentModel reasoning / chain-of-thought delta (thinking models only)
tool_callname, argsAgent decides to call a tool
tool_call_chunkargs_deltaStreaming tool argument delta (when model outputs args in chunks)
tool_resultname, contentTool return value (truncated to 500 chars)
tokencontentFinal answer token delta (concatenate for full response)
doneNormal completion
errorcontentError 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. /chat is for UIs that need to show the agent's thinking process.

3.4 Conversation management

PathMethodPurpose
/conversationsPOSTExplicitly create a conversation (usually unnecessary — /chat/completions auto-creates)
/conversations/{conv_id}GETFetch full conversation history
/conversations/{conv_id}/filesGETList files generated by the Agent in this conversation
/conversations/{conv_id}/files/{path}GETDownload generated files (images, docs, etc.); supports ?token= for <img src> auth
/conversations/{conv_id}/media-tokenGETGet a short-lived media access token (for standalone chat pages)

POST /conversations request / response

jsonc
// 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

jsonc
{
  "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_id404 {"detail": "Conversation not found"}.