Build and operate cloud-based AI agents through the Qoder Cloud Agents Service (CAS) REST API.
A cloud agent runs in a container hosted on the Cloud Agents platform, decoupled from the user's local machine. Typical scenarios:
-
Field name is agent, not agent_id — POST /sessions body uses "agent": "<id>". Using agent_id returns 400.
-
Events must be wrapped in events array — POST /sessions/{id}/events body is {"events": [{type, content}]}, NOT a bare event object. Bare object returns 400 "Field 'events' is required."
-
Use session.status_idle as stop signal and turn boundary — Do not rely on span.model_request_end or any other event. idle fires first, carries usage + stop_reason, and signals it is safe to send the next message. Sending while still running is undefined behavior. See shared/client-patterns.md Pattern 1.
-
Cold start delay — First event after session.status_running may take 5-60 seconds (container provisioning). Do not timeout prematurely.
-
Environment must exist and be ready — POST /sessions fails if the environment is archived or not in status: ready.
-
Cancel is async — POST /cancel returns 202 with {"status":"canceling"}. The session settles to idle asynchronously. See shared/client-patterns.md Pattern 3.
-
agent.message content is array format — [{"text":"...","type":"text"}], not a plain string. Always access content[0].text.
-
JSON construction — When building request bodies, always use proper JSON encoding (e.g., jq -n --arg). Never interpolate variables directly into JSON strings.
-
SSE heartbeat is dual-line — Both : heartbeat (comment) and event: heartbeat\ndata: {} are sent. Filter both when parsing.
-
Pagination uses cursor, not offset — Use after_id/before_id params, not page numbers.
-
Environment creation requires config — POST /environments body must include "config": {"type":"cloud","networking":{"type":"unrestricted"}}. Sending only {name} returns 400.
-
Model name is ultimate — Use "model": "ultimate" when creating agents. Other model names (e.g. qwen-max) may trigger session.error with retry exhaustion.
-
Back off on 429 — Under bursty load the API rate-limits with 429. Honor Retry-After or use exponential backoff with jitter; don't retry immediately. See shared/client-patterns.md Pattern 8.
-
PAT location is fixed — quote, don't paraphrase — When the user asks where to get a PAT, output one of the URLs/paths listed under "Before You Start §1" verbatim. Do not invent any other URL or menu wording, and do not add disclaimers about places the PAT is not found — just give the correct answer.
-
Pass bulk data through the Files API, not the message body — When the user wants the agent to process a non-trivial dataset (CSV / JSON / log / transcript / source dump), upload it with POST /files and attach the returned file_id to the session via resources: [{"file_id": "file_xxx"}] on POST /sessions. Inside the container the file is mounted at /data/<file_id>; instruct the agent to read that path with its built-in Bash/Read tools. Pasting the rows directly into events[].content exhausts the model context budget and the turn ends before any work is done.