https://<name>.cycls.ai. This page lists
its endpoints. For the Cycls Cloud control plane, see the
API reference tab.
Authentication: routes marked authenticated require
Authorization: Bearer <token>, where the token comes from the configured
identity provider. Without Web().auth(...), the state routers are
not installed and only the public routes exist.
Workspace selection: in multi-workspace mode, send
X-Workspace: <id> to act inside a team workspace. No header means the personal
one.
Chat
?id=<chat_id> to continue an existing chat. Without it, a new chat id is
generated.
/chat/completions sends each event as delta.content unchanged: text arrives
as a string and a component as its dict. It ignores detach and sends no chat
id. Use POST / when you want the run protocol below.
/transcribe takes m4a, mp4, webm, ogg, mp3 or wav, transcribes it with the
model .voice() names and returns {"text": ...}
alone. A recording the service could not transcribe is a 502. It answers 501 when
voice input is off: .voice(False), or no .voice() and no OPENAI_API_KEY.
Run options
Besidesmessages, the body of POST / takes:
The stream
The first SSE frame is{"type": "chat_id", "chat_id": "..."}. Components
follow, then data: [DONE]. An unhandled error ends the stream with an error
callout that carries error_id, the reference to
find in the logs.
A chat runs one turn at a time. A request while one is running gets 409
{"error": "run_in_progress"} with Retry-After: 2.
Following a run
A detached run outlives its stream. PollGET /chats/{id}?since=<n>, which
returns the turns after n and the state of the run:
POST /chats/{id}/stop cancels the run on whichever instance holds it and
answers 202 {"stopping": true}. Send {"take_back": "<sha256>"}, the hash of
the prompt being stopped, and the run deletes that turn as it ends if it kept
nothing after it. The reply then adds taken_back. A run that already finished
answers {"stopping": false}, and a chat with no run answers 404.
Configuration and metadata
Chats (authenticated)
Files (authenticated)
Rendering variants for office files:
?as=slides returns per-slide images and
?as=pdf returns a converted PDF. Both require the office render service to be
configured. See Files and the canvas.
Trash (authenticated)
Sharing
POST /share takes {"path": "chat/<id>"} or {"path": "file/<path>"}, and an
optional audience: "public", the default, or "org:<id>", which only
signed-in members of that organization can open.
Workspaces (authenticated)
Installed only whenWeb().workspaces() is enabled.
Connectors (authenticated)
Installed when connectors are declared.Tool settings (authenticated)
Skills (authenticated)
The routes behind the Skills tab. See Skills. Ascope is me, workspace or org, and GET /skills lists the ones the
caller may publish to.
Memory (authenticated)
The person’s entries in thedatabase tool for the active workspace. Settings
lists them as Memory. Turning Memory off is PUT /tools/database with
{"mode": "never"}.
App data (authenticated)
Used by apps the agent builds. See theApps tool in
Tools.
Rows belong to the workspace and its members share them.
?who=me reaches the
caller’s own rows instead, and workspace admins can pass a member’s user id, or
all for everyone’s. A write with the ?version= of the last read lands only if
the row has not changed since, else 412. An empty ?version= writes only a row
that does not exist yet. Without it, the last write wins.
Your own routes
Add routes with.server, which is replayed onto the real router inside the
container:
Storage layout
Sessions and files live under/workspace/<scope>/, where the scope is the user
or the active workspace. Path traversal is rejected.
Next
Environment variables
Every variable the SDK and runtime read.