Overview
The Chat Completions API is fully compatible with OpenAI’s API format, allowing you to use the OpenAI Python SDK, JavaScript SDK, or any OpenAI-compatible client.Model Parameter (Optional): The
model parameter is optional and primarily for SDK compatibility. Your organization’s orchestrator agent automatically uses the configured LLM model.If you’re using an OpenAI SDK that requires the model parameter, you can pass any value (e.g., "junis-orchestrator") for compatibility.Prerequisites
Endpoint
Authentication
Include your API key in theX-API-Key header:
orchestrator:invoke (orchestrator:stream for stream: true, agents:invoke when target_agent_id is set)
See Authentication for details.
Request Format
Basic Request
cURL
Request Parameters
Delegation (
on_behalf_of) is designed for partner services that provision
end-user accounts via User Provisioning.
Pending members are allowed so provisioned users work before their first login.Message Format
Messages follow the OpenAI format:system: System instructions (optional, rarely needed with Junis)user: User messagesassistant: Assistant responses (for conversation context)tool: Tool call results (for function calling)
Response Format
Non-Streaming Response
Status Code:200 OK
Response Body:
Response Fields
Streaming Mode
Enable real-time token-by-token streaming withstream: true.
Streaming Request
cURL
Streaming Response Format
Server-Sent Events (SSE) format:- Each line starts with
data: - First chunk contains
role - Subsequent chunks contain
contentdeltas - Final chunk has
finish_reason - Every chunk includes
session_idfor conversation continuity - Stream ends with
data: [DONE] - Lines starting with
:(for example: keepalive) are SSE comments sent every 15 seconds while the server is still preparing the answer (including the first-time build of your organization’s agents). Standard SSE/OpenAI clients ignore them.
Low-latency first turn: direct routing, warmup, per-request context
The first message of a new session normally costs one extra LLM call: the orchestrator reads the request and decides which agent should answer (transfer_to_agent). Measured in production this routing call takes about 2 seconds (p50) before the answering agent even starts. Later turns in the same session skip it — Junis resumes the agent that answered last.
If your application already knows which agent should answer (for example a fixed “counselor” or “support” agent), you can skip the routing call on the first turn too.
target_agent_id — skip the routing call
cURL
extra_context — context for this turn only
extra_context is appended as a non-persistent trailing block after the conversation, for this request only. It is never written to the session and never merged into the system instruction, so it cannot pollute later turns or break prompt caching. Since October 2026 it is delivered to the agent that actually answers (orchestrator-routed sub-agent, target_agent_id target, or /agents/{agent_id}/completions), not only to the orchestrator.
- Maximum 65,536 characters (
422if exceeded). - It counts as uncached input tokens on every call that receives it — send what the turn needs, not your whole database.
- If your organization prefers the previous behavior (context on the orchestrator call only), contact us and we will turn off delivery to the answering agent for your organization. Sub-agent requests then match the pre-October behavior byte for byte. Note that on
target_agent_idturns the orchestrator does not run, so with delivery turned off no model call receivesextra_context(or the user’s memory) on those turns — the same as before October.
Warmup — build the agents before the first message
Your organization’s agents are built lazily per (organization, user) on the server that receives the request, so the first message of a newly provisioned user pays that build (fractions of a second for small squads, several seconds for squads with many tools). CallPOST /v1/warmup right after provisioning the user and the first message finds everything ready.
Multi-Agent Events
For Advanced Integrations: Junis streams additional agent lifecycle events alongside standard OpenAI chunks. These events have no
choices field, so standard OpenAI SDKs automatically ignore them - ensuring 100% backward compatibility.Parse these events to build rich UIs that show which agents are processing your request.Event Types
SSE Stream Example (Multi-Agent)
Parsing Agent Events (Python)
Parallel Agent Support
When multiple agents run concurrently (Parallel Agent), usetoken_agent events to correctly attribute tokens:
Session Management
Junis supports explicit session management viasession_id parameter, allowing you to control conversation context precisely.
How Sessions Work
Session ID Usage
Behavior:Example: Continuing a Conversation
Viewing Sessions
Retrieve your sessions via the Sessions API:Function Calling (Tool Use)
When a supported keyword is detected in the assistant’s response, the API returns atool_calls object with finish_reason: "tool_calls".
Error Handling
Common Errors
Error Types
Best Practices
- Use Streaming: Enable
stream: truefor long responses to provide real-time feedback - Handle Rate Limits: Implement exponential backoff when hitting rate limits (see error codes above)
- Keep Message History Concise: Trim old messages to avoid token limits (keep last 10-20 messages)
- Secure API Keys: Never hardcode API keys; use environment variables
- Log Requests: Log requests and responses for debugging and monitoring
Response Parameters
Temperature Guide
Next Steps
Sessions API
Retrieve and manage conversation sessions
Error Codes
Complete error reference
Rate Limits
Understand rate limiting
