Skip to main content
A deployed agent is an HTTP service at 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

Add ?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

Besides messages, 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. Poll GET /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 when Web().workspaces() is enabled.

Connectors (authenticated)

Installed when connectors are declared.

Tool settings (authenticated)

Skills (authenticated)

The routes behind the Skills tab. See Skills. A scope is me, workspace or org, and GET /skills lists the ones the caller may publish to.

Memory (authenticated)

The person’s entries in the database 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 the Apps 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.