Use an Agent from Any OpenAI Client
Every agent is a model behind an OpenAI-compatible endpoint: point an OpenAI SDK or a tool that takes a base URL at it, and the agent answers with its own tools, skills and knowledge.
Every agent in your workspace is also a model behind an OpenAI-compatible endpoint. Anything that speaks OpenAI's Chat Completions API can talk to it: the official openai SDKs, and tools that let you set a base URL. The agent answers as it does in Chat, with its own system prompt, model, tools, skills and knowledge bases.
The endpoint
| Where | Base URL |
|---|---|
| Self-hosted | http://localhost:3000/api/v1/openai — your SynapseOrch address and the web UI's port |
| SynapseOrch Cloud | https://api.synapseorch.com/api/v1/openai |
Authenticate with an API key as the Bearer token, which every OpenAI client sends when you give it the key.
| Method | Path | What it does |
|---|---|---|
GET | /models | Lists the agents the key may use, workflow agents included |
GET | /models/{id} | One agent |
POST | /chat/completions | One turn with the agent the model names; stream: true for SSE |
Name the agent as the model
model is the agent's id or its exact name, in any case. GET /models lists both, so "model": "Support Bot" and "model": "agent_7f3a…" reach the same agent. An unknown name is a 404 with the code model_not_found.
Python
from openai import OpenAI
client = OpenAI(base_url="https://api.synapseorch.com/api/v1/openai", api_key="sk-syn-...")
reply = client.chat.completions.create(
model="Support Bot",
messages=[{"role": "user", "content": "Where is my order 4417?"}],
)
print(reply.choices[0].message.content)JavaScript
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://api.synapseorch.com/api/v1/openai", apiKey: "sk-syn-..." });
const stream = await client.chat.completions.create({
model: "Support Bot",
messages: [{ role: "user", content: "Where is my order 4417?" }],
stream: true,
});
for await (const chunk of stream) process.stdout.write(chunk.choices[0]?.delta?.content ?? "");curl
curl https://api.synapseorch.com/api/v1/openai/chat/completions \
-H "Authorization: Bearer sk-syn-..." \
-H "Content-Type: application/json" \
-d '{"model": "Support Bot", "messages": [{"role": "user", "content": "Hi"}]}'The conversation is the request
OpenAI's API is stateless, and so is this endpoint: each request carries the whole conversation.
- The earlier
userandassistantmessages are the agent's history. - The last message must be the user's: it is the turn the agent answers.
- A
systemordevelopermessage is added after the agent's own system prompt, as instructions from the calling app. The agent's own prompt comes first, and wins where the two disagree. - Nothing is saved as a conversation in Chat. Every turn appears in Runs › Logs, with the source
openai.
What the agent decides, and what you cannot send
The agent's tools run on SynapseOrch's side, as they do in Chat. So a request cannot bring its own tools:
| Sent | Answer |
|---|---|
tools, functions with any entries, or a tool_choice other than none or auto | 400, code tools_unsupported |
A message with the tool or function role, or an assistant message with tool_calls | 400, code tools_unsupported |
n above 1 | 400 |
An image as an https:// URL | 400: send images inline, as data:image/…;base64,… URIs |
temperature, top_p, max_tokens, seed and other sampling fields | Accepted and ignored: the agent's own model settings apply |
On a self-hosted install, images sent as data URIs reach an agent whose model reads images; one that cannot is a 400. On SynapseOrch Cloud, images are not accepted on this endpoint yet.
Streaming
With stream: true the answer arrives as chat.completion.chunk events while the agent's model writes it, ending with data: [DONE]. The first chunk carries the role, and the last carries finish_reason: "stop". Set stream_options: {"include_usage": true} for a final chunk with usage.
An agent often works in rounds: it calls a tool, reads the result and then answers. During a tool round the stream stays open with SSE comments, which every OpenAI client skips. Text a model writes before it calls a tool ("Let me look that up.") is sent as it comes, because a stream cannot take words back, and the answer that follows starts a new paragraph. A workflow agent's answer arrives in one piece when its workflow ends. A Team agent answers with its lead's final answer only; its members' work is not streamed.
The answer is not streamed when the model's provider does not stream (a CLI model, a local Hugging Face model). It then arrives whole, as one chunk.
When a person has to approve
An agent's tool policy can require a person to approve a call. A program calling the endpoint cannot press Approve, so the turn parks instead:
- The answer says a person has been asked and someone will follow up, with
finish_reason: "stop". - The response carries
"synapse": {"status": "awaiting_approval", "approval_id": "…", "session_id": "…"}. OpenAI's SDKs keep unknown fields, so you can read it. - The bell asks the workspace's builders and admins, and the question also appears under Waiting on you. Approving there carries the turn on from where it stopped, and a second item says how it ended.
- Nobody answering within 24 hours expires the call. It is not run.
A Team agent's member that needs approval parks the turn the same way, and the client is told the answer waits for a person.
Usage, billing and limits
Every answer has a usage block (and a streamed one has one when asked): the tokens of all the turn's model calls, with prompt_tokens_details.cached_tokens when a cache served some of the input.
On SynapseOrch Cloud a turn is billed as a chat turn: execution credits by its minutes, plus the model calls it makes. It is subject to the key's limits: 300 requests a minute, 60 turns started a minute, and 25 open streams. A workspace out of credits answers 402 with the code insufficient_quota, and a limit answers 429 with Retry-After.
Errors
Errors are in OpenAI's shape, so the SDKs raise their usual exceptions:
{"error": {"message": "The model 'gpt-4o' does not exist: …", "type": "invalid_request_error", "param": "model", "code": "model_not_found"}}A model failure in the middle of a stream is an error event, then [DONE]. Its message says what kind of failure it was (a provider out of credit, a rate limit, a provider that could not be reached) and never quotes the provider.
Synapse as an MCP Server
Connect Claude Code, Cursor or any MCP client to Synapse: build agents and workflows, run them, answer their questions and read the results — every workflow is a tool of its own.
Webhooks
On SynapseOrch Cloud, have Synapse POST a signed event to your URL when a knowledge base's document is indexed, partly indexed or failed, or a base is rebuilt.