KsADK

Remote Runtime API

This reference describes the public-safe runtime API shape after an agent or runtime product is deployed. The externally visible base URL is the hosted PublicEndpoint returned by the control plane.

Use placeholders in public examples:

https://<public-endpoint>

Entry Model

Remote runtime entry and runtime type

The runtime pod may implement local routes, but public callers should treat the gateway-facing PublicEndpoint routes as the contract.

Authentication

ClientRecommended authentication
SDK, CLI, automationAuthorization: Bearer <api_key>
Hosted browser sessionae_ui_session cookie created by the hosted link flow
Hermes terminal WebSocketbearer auth plus Sec-WebSocket-Protocol: ks-terminal.v1

External callers should not manufacture internal gateway headers such as X-Auth-Agent-Id, X-Auth-Account-Id, or runtime-specific forwarded headers.

Bearer Token Enforcement

The hosted runtime requires Authorization: Bearer <token>. The local dev server does not enforce auth by default, but in production the gateway injects and validates the Bearer token. Clients should always send it to keep local and hosted behavior consistent.

Common Headers

HeaderUse
Authorization: Bearer <api_key>API calls through the public endpoint
Content-Type: application/jsonJSON requests
Accept: application/jsonNon-streaming responses
Accept: text/event-streamStreaming responses

The multipart/form-data boundary for upload routes should be generated by the HTTP client.

Runtime Types

RuntimePrimary public surface
Code-framework Agent/v1/responses, /v1/chat/completions, workspace files, hosted UI actions
Hermesdashboard, /v1/* proxy, terminal WebSocket, workspace files
OpenClawOpenClaw gateway plus KsADK workspace files

OpenAI-Compatible Routes

POST /v1/responses

The entry point for Responses-compatible clients.

FieldMeaning
inputUser input string, or message/content array
modelOptional model override
instructionsRequest-level system/developer instructions
conversationStable conversation id or { "id": "..." }
previous_response_idContinuation handle for compatible clients
safety_identifierStable end-user id, hash before sending
streamtrue returns SSE
metadataRuntime-reserved request metadata
curl -sS https://<public-endpoint>/v1/responses \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{"input":"hello","stream":false}'

POST /v1/chat/completions

The entry point for Chat Completions-compatible clients.

curl -sS https://<public-endpoint>/v1/chat/completions \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{"model":"my-model","messages":[{"role":"user","content":"hello"}]}'

Responses and Chat Completions keep their own protocol semantics at the public boundary. KsADK normalizes both into runner input before invoking framework code.

Hosted UI Actions

The hosted UI uses action-style routes to manage sessions, events, uploads, workspace files, cancellation, and model listing. Public API clients should prefer the OpenAI-compatible /v1/* routes and only target action routes when integrating the hosted UI surface directly.

All action paths live under POST /agentengine/api/v1/* (download surfaces are GET) and return a unified action envelope:

envelope.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "RunAgent",
  "Data": { /* action-specific payload */ }
}
GroupPurposeActions
SessionsCreate, get, list, delete sessions, read projected chat messagesCreateSession, GetSession, ListSessions, ListSessionMessages, DeleteSession
RunsInvoke or cancel a run, subscribe to eventsRunAgent, SubscribeRunEvents, CancelRun
EventsList historical session events with incremental resume and older-page cursorsListSessionEvents
FilesUpload, download attachments, workspace files, export archiveUploadFile, AttachmentContent, ListWorkspaceFiles, AddWorkspaceFile, DeleteWorkspaceFile, GetWorkspaceFileContent, ExportWorkspaceZip
ModelsList the available model catalogListAgentModels
UI BootstrapBootstrap metadata for UI rendering and capability discoveryGetAgentUiBootstrap

New in 0.6.7

checkpoint/resume and GetAgentUiBootstrap capability visibility are governed by the RuntimeCapabilities and RunLifecycle returned by bootstrap. Public API clients usually do not target these action routes directly; prefer the OpenAI-compatible /v1/*.

Sessions

  1. Probe capabilities: call GetAgentUiBootstrap first to check Capabilities.WorkspaceFiles, Capabilities.ResumeRun, etc.
  2. Create a session: CreateSession, take Session.SessionId.
  3. Pull history: ListSessions for the sidebar and ListSessionMessages for chat history; use ListSessionEvents directly only for debugging or raw timelines.
  4. Start a run: RunAgent (foreground or background), subscribe to progress via SubscribeRunEvents.
  5. Reclaim a session: DeleteSession to release persisted records.

CreateSession

Creates (or reuses) a session. When SessionId is omitted, the runtime generates one.

POST /agentengine/api/v1/CreateSession, JSON body:

FieldTypeRequiredNotes
AgentIdstringyesTarget agent id
UserIdstringnoDefaults to user
SessionIdstringnoReuse an existing session; runtime generates one when omitted
request.json
{
  "AgentId": "my-agent",
  "UserId": "user",
  "SessionId": "local-demo-session"
}
response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "CreateSession",
  "Data": {
    "Session": {
      "SessionId": "local-demo-session",
      "AgentId": "my-agent",
      "UserId": "user",
      "Title": "New session",
      "TitleSource": "fallback_first_prompt",
      "Summary": null,
      "FirstPrompt": "",
      "LastPrompt": "",
      "ActiveInvocationId": "",
      "ActiveRunStatus": "",
      "ActiveRunMode": "unknown",
      "ActiveRunTrigger": "unknown",
      "ActiveRunUpdatedAt": "",
      "Model": null,
      "ContextUsage": null,
      "TokenUsage": null,
      "State": {},
      "CreatedAt": 1719900000.0,
      "UpdatedAt": 1719900000.0,
      "Version": 1
    }
  }
}

Session payload fields:

FieldNotes
SessionId / AgentId / UserIdSession primary key triple
Title / TitleSourceSession title and its source (fallback_first_prompt, heuristic, etc.)
SummaryRuntime-maintained session summary
FirstPrompt / LastPromptTruncated first/last user message preview
ActiveInvocationId / ActiveRunStatusActive run invocation and status for this session; stale orphaned active runs are read as interrupted
ActiveRunMode / ActiveRunTrigger0.6.9+ two independent run dimensions: background / foreground / unknown and new_run / checkpoint_resume / approval_resume / unknown
ActiveRunUpdatedAt0.6.9+ timestamp from active_run itself, mainly for diagnostics; orphan detection uses the session UpdatedAt heartbeat
ModelModel metadata from the most recent run when available
ContextUsage0.6.9+ latest-turn context-window usage: used_tokens, cached_tokens, context_window_tokens, percent
TokenUsage0.6.9+ cumulative session token usage: input_tokens, output_tokens, total_tokens, turns, last_response_id, and detail fields
StateSession state dict (sanitized)
CreatedAt / UpdatedAt / VersionTimestamps and version
ContinuityOptional: continuity info from the runner adapter
StatusScenariodetail
400Missing AgentIdPydantic validation failure
503Session backend unavailable{"code":"session_backend_unavailable","message":...}

ListSessions

Paginated list of sessions for an Agent/User, page-based pagination.

POST /agentengine/api/v1/ListSessions:

FieldTypeRequiredNotes
AgentIdstringyesTarget agent id
UserIdstringnoDefaults to user
Pageintno1-based, default 1, min 1
PageSizeintnoDefault 20, range 1..200
request.json
{
  "AgentId": "my-agent",
  "UserId": "user",
  "Page": 1,
  "PageSize": 20
}
response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "ListSessions",
  "Data": {
    "Sessions": [ /* Session payload, same as CreateSession */ ],
    "Total": 42,
    "Page": 1,
    "PageSize": 20
  }
}

Pagination fields:

FieldNotes
TotalTotal session count for this Agent/User
Page / PageSizeCurrent page and page size (echoed back)

The runtime computes offset as (Page - 1) * PageSize.

GetSession

Fetch a single session with its latest events.

POST /agentengine/api/v1/GetSession:

FieldTypeRequiredNotes
SessionIdstringyesTarget session id
request.json
{ "SessionId": "local-demo-session" }
response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "GetSession",
  "Data": {
    "Session": { /* same Session payload as CreateSession */ }
  }
}
StatusScenariodetail
404Session not foundSession not found

DeleteSession

Delete a session and cancel any detached stream still running for it.

POST /agentengine/api/v1/DeleteSession:

FieldTypeRequiredNotes
SessionIdstringyesTarget session id
request.json
{ "SessionId": "local-demo-session" }
response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "DeleteSession",
  "Data": { "Deleted": true }
}

Side Effect

Before deletion, the runtime cancels detached background streams for that session to avoid dangling in_progress run_status events.

StatusScenariodetail
404Session not foundSession not found

Runs

RunAgent

Invoke an agent for one conversation turn. Supports foreground sync, foreground streaming, and background execution modes.

POST /agentengine/api/v1/RunAgent, JSON body (based on RunAgentActionRequest):

FieldTypeRequiredNotes
AgentIdstringyesTarget agent id
MessagesarraynoMessage array (Chat Completions style); mutually exclusive with ResponsesInput
ResponsesInputanynoResponses-style input; mutually exclusive with Messages
UserIdstringnoDefaults to user
AccountIdstringno0.6.5+ account-scoped id, passed through to the runner
SessionIdstringnoAssociated session; runtime creates one when omitted
InvocationIdstringnoCaller-provided invocation id; runtime generates one when omitted
ApiFormatstringnoresponses (default) or chat_completions
Streamboolnotrue returns SSE; default false
Backgroundboolno0.6.5+ true returns a job handle immediately, runs in background, progress via SubscribeRunEvents; default false
ModelstringnoModel or agent name override
ModelMetadataobjectnoModel metadata, including reasoning / multimodal / context_window_tokens
ModelOptionsobjectnoRequest-level model options (temperature, max_tokens, etc.) passed through to the runner
PreviousResponseIdstringnoResponses continuation handle; written into request metadata

Foreground sync call:

request.json
{
  "AgentId": "my-agent",
  "Messages": [{"role": "user", "content": "hello"}],
  "ApiFormat": "responses",
  "Stream": false
}

Background execution:

background.json
{
  "AgentId": "my-agent",
  "Messages": [{"role": "user", "content": "summarize the workspace"}],
  "Background": true,
  "InvocationId": "inv_demo_001",
  "AccountId": "acct_42",
  "Model": "glm-5.1",
  "ModelMetadata": {"reasoning": true, "multimodal": false, "context_window_tokens": 128000},
  "ModelOptions": {"temperature": 0.2, "max_tokens": 4096}
}

Background and Stream are mutually exclusive

Background: true ignores Stream and returns a job handle immediately. A foreground Stream: true returns SSE. The two cannot be enabled together.

Foreground sync (Background: false, Stream: false) returns a Responses or Chat Completions payload wrapped in the action envelope:

response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "RunAgent",
  "Data": {
    "id": "resp_a1b2c3",
    "object": "response",
    "status": "completed",
    "model": "glm-5.1",
    "output": [{"type": "message", "role": "assistant", "content": [{"type": "output_text", "text": "..."}]}],
    "output_text": "...",
    "session_id": "local-demo-session"
  }
}

Background execution (Background: true) returns a job handle immediately:

background-response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "RunAgent",
  "Data": {
    "InvocationId": "inv_demo_001",
    "Status": "running",
    "Background": true,
    "SubscribeUrl": "/agentengine/api/v1/SubscribeRunEvents?SessionId=local-demo-session&InvocationId=inv_demo_001"
  }
}

Background response fields:

FieldNotes
InvocationIdRun invocation id, used for subscribe and cancel
Statusrunning means the background task is ready
BackgroundAlways true
SubscribeUrlRelative path; prepend the host to use as the SSE subscribe entry

Foreground Stream: true returns text/event-stream; events are normalized by the runtime before delivery:

sse
curl -N https://<public-endpoint>/agentengine/api/v1/RunAgent \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{"AgentId":"my-agent","Messages":[{"role":"user","content":"count to three"}],"Stream":true}'

Clients should handle text deltas, tool events, errors, and completion events.

StatusScenariodetail
400Both Messages and ResponsesInput, or neitherPydantic / runtime validation failure
409A resume for this session is already running{"code":"resume_already_running",...}
500Runner not initialized or load failureRunner 未初始化

0.6.5+ pass-through fields

AccountId, InvocationId, ModelMetadata, and ModelOptions are passed through to the runner unchanged, enabling per-account isolation of Skill/Workspace/Sandbox/Memory and request-level model overrides. When AccountId is omitted, the runner falls back to the runtime default account.

SubscribeRunEvents

Subscribe to run events for an invocation via SSE. Supports a 5-minute reconnect window.

GET /agentengine/api/v1/SubscribeRunEvents, parameters via query string:

ParamTypeRequiredNotes
SessionIdstringyesTarget session id
InvocationIdstringyesTarget run invocation id
AfterSeqIdintnoOnly emit events with SeqId > AfterSeqId; default 0
subscribe-url
/agentengine/api/v1/SubscribeRunEvents?SessionId=local-demo-session&InvocationId=inv_demo_001&AfterSeqId=12

Accept: text/event-stream. Each event is data: <json>\n\n; on terminal status the stream emits data: [DONE]\n\n and closes:

events.sse
data: {"EventId":"evt_1","SessionId":"local-demo-session","InvocationId":"inv_demo_001","EventType":"run_status","Content":{"status":"in_progress"},"SeqId":13,"Timestamp":1719900001.0}

data: {"EventId":"evt_2","EventType":"tool_result","Content":{...},"SeqId":14,...}

data: {"EventId":"evt_3","EventType":"run_status","Content":{"status":"completed"},"SeqId":15,...}

data: [DONE]

Event payload fields:

FieldNotes
EventId / SessionIdEvent and its session
InvocationIdAssociated run invocation id
AuthorEvent author (agent or user)
EventTypeEvent type (run_status, tool_result, run_checkpoint, etc.)
ContentEvent content dict
TimestampEvent timestamp
SeqIdMonotonic per-session sequence number, used for resumption
MetadataEvent metadata

5-minute reconnect window

A streaming connection has a maximum lifetime of 5 minutes (deadline = now + 5min). When the deadline is reached the connection closes silently and does not emit [DONE]. Clients should record the largest SeqId consumed and pass it as AfterSeqId on the next reconnect; as long as the run has not reached a terminal status, reconnecting continues to deliver subsequent events.

Terminal statuses (any one triggers [DONE]):

statusMeaning
completedNormal completion
failed / errorFailure
cancelled / canceledCancelled
abortedAborted
interruptedInterrupted
StatusScenariodetail
400Missing SessionId or InvocationIdSessionId and InvocationId are required

CancelRun

Request cancellation of an in-flight run (both detached stream and runner channel).

POST /agentengine/api/v1/CancelRun:

FieldTypeRequiredNotes
AgentIdstringnoTarget agent id (not currently enforced)
InvocationIdstringyesRun invocation id to cancel
request.json
{ "AgentId": "my-agent", "InvocationId": "inv_demo_001" }
response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "CancelRun",
  "Data": {
    "Cancelled": true,
    "Found": true,
    "Status": "cancelling",
    "RunnerCancelStatus": "accepted"
  }
}
FieldNotes
CancelledWhether cancellation was initiated (true if either detached stream or runner accepted)
FoundWhether a detached stream was located
StatusAggregated status: cancelling / not_found / unsupported / error
RunnerCancelStatusRunner-side result: accepted / cancelling / cancelled / not_found / unsupported / error

Events

ListSessionEvents

Paginated list of historical events for a session. Without a seq cursor, Offset / Limit page backward from the latest event window. AfterSeqId is for reconnect/incremental reads; BeforeSeqId is for loading older history.

POST /agentengine/api/v1/ListSessionEvents:

FieldTypeRequiredNotes
SessionIdstringyesTarget session id
Offsetintno0-based offset, default 0
LimitintnoPage size, min 1
AfterSeqIdintno0.6.9+ return events with SeqId > AfterSeqId for reconnect catch-up
BeforeSeqIdintno0.6.9+ return events with SeqId < BeforeSeqId for older pages
request.json
{ "SessionId": "local-demo-session", "Offset": 0, "Limit": 50 }
response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "ListSessionEvents",
  "Data": {
    "Events": [ /* event payload, same as SubscribeRunEvents */ ],
    "Total": 128,
    "Offset": 0,
    "Limit": 50,
    "AfterSeqId": null,
    "BeforeSeqId": null
  }
}

Pagination fields:

FieldNotes
TotalTotal event count for this session
OffsetCurrent offset (defaults to 0)
LimitCurrent page size (falls back to the returned count when not sent)
AfterSeqId / BeforeSeqIdEchoed seq cursors; they move in opposite directions and should not be mixed

ListSessionMessages

Project the raw event log into chat messages that the Web UI can render directly. The server handles assistant snapshot de-duplication, reasoning merging, tool / approval pairing, and attachment normalization so clients do not need to reconstruct messages from ListSessionEvents.

POST /agentengine/api/v1/ListSessionMessages:

FieldTypeRequiredNotes
AgentIdstringnoWhen present, the server fetches runtime ListSessionEvents and projects them in one place; when omitted, hosted reads the local session store
SessionIdstringyesTarget session id
LimitintnoMaximum messages to return, default 50, range 1..200
AfterSeqIdintnoReturn incremental messages with SeqId > AfterSeqId; used for reconnect catch-up and not truncated to Limit
BeforeSeqIdintnoReturn the latest page before SeqId < BeforeSeqId; used for loading older history
IncludeReasoningboolnoInclude Reasoning[] inside assistant messages
IncludeToolEventsboolnoInclude ToolEvents[] inside assistant messages
IncludeAttachmentsboolnoInclude Attachments[] on user messages, default true
request.json
{
  "SessionId": "local-demo-session",
  "Limit": 50,
  "IncludeAttachments": true
}
response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "ListSessionMessages",
  "Data": {
    "SessionId": "local-demo-session",
    "Messages": [
      {
        "MessageId": "evt_user_1",
        "Role": "user",
        "Content": {"text": "Summarize this file"},
        "SeqId": 21,
        "InvocationId": "inv_demo_001",
        "Timestamp": 1719900001.0,
        "Attachments": [
          {
            "file_uri": "ae-upload://abc123_report.pdf",
            "name": "report.pdf",
            "mime": "application/pdf",
            "size": 204800,
            "url": "/agentengine/api/v1/AttachmentContent?FileUri=ae-upload%3A%2F%2Fabc123_report.pdf",
            "is_image": false
          }
        ]
      },
      {
        "MessageId": "evt_assistant_1",
        "Role": "assistant",
        "Content": {"text": "Here is the summary..."},
        "SeqId": 24,
        "InvocationId": "inv_demo_001",
        "ResponseId": "resp_a1b2c3",
        "TraceId": "trace_abc",
        "RootSpanId": "span_root"
      }
    ],
    "LatestSeqId": 24,
    "HasMore": true,
    "NextCursor": 20
  }
}

Pagination fields:

FieldNotes
LatestSeqIdSeqId of the last message in the page; pass it to SubscribeRunEvents(AfterSeqId=...) as the reconnect starting point
HasMoreWhether older messages remain
NextCursorOlder-page cursor; pass it as BeforeSeqId=NextCursor on the next request

Reconnect detection

ListSessionMessages only projects historical messages. To decide whether an SSE stream should reconnect, read GetSession.ActiveRunStatus / ActiveInvocationId, then call SubscribeRunEvents(AfterSeqId=LatestSeqId).

Files

UploadFile

Upload an attachment and return an ae-upload:// handle for use by RunAgent / AttachmentContent.

POST /agentengine/api/v1/UploadFile, multipart/form-data:

FieldTypeRequiredNotes
filebinaryyesUpload file content
upload
curl -sS https://<public-endpoint>/agentengine/api/v1/UploadFile \
  -H "Authorization: Bearer <api_key>" \
  -F "file=@report.pdf"
response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "UploadFile",
  "Data": {
    "FileData": {
      "fileUri": "ae-upload://abc123_report.pdf",
      "displayName": "report.pdf",
      "mimeType": "application/pdf",
      "sizeBytes": 204800
    }
  }
}

AttachmentContent

Read the bytes of an uploaded attachment by its ae-upload:// handle, returning the original content-type.

GET /agentengine/api/v1/AttachmentContent?FileUri=...:

ParamTypeRequiredNotes
FileUristringyesfileUri returned by UploadFile
download-url
/agentengine/api/v1/AttachmentContent?FileUri=ae-upload://abc123_report.pdf
binary
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: inline; filename="report.pdf"

<binary bytes>

Prefix Resolution

Paths with the ae-upload:// prefix resolve to hosted upload content and return its byte stream; paths without that prefix are treated as workspace-relative paths.

StatusScenariodetail
404Attachment not foundAttachment not found

ListWorkspaceFiles

List workspace file entries (proxied to /_ksadk/workspace/v1/entries).

POST /agentengine/api/v1/ListWorkspaceFiles:

FieldTypeRequiredNotes
AgentIdstringnoTarget agent id (not currently enforced)
PathstringnoWorkspace-relative path, default .
RecursiveboolnoRecurse into subdirectories, default false
request.json
{ "Path": ".", "Recursive": true }
response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "ListWorkspaceFiles",
  "Data": {
    "Entries": [
      { "Path": "notes/todo.md", "Type": "file" },
      { "Path": "notes/", "Type": "dir" }
    ]
  }
}

AddWorkspaceFile

Add or overwrite a workspace file (proxied to /_ksadk/workspace/v1/files/<path>).

POST /agentengine/api/v1/AddWorkspaceFile, multipart/form-data:

FieldTypeRequiredNotes
filebinaryyesUpload file content
PathstringyesWorkspace-relative path
AgentIdstringnoTarget agent id (not currently enforced)
upload
curl -sS https://<public-endpoint>/agentengine/api/v1/AddWorkspaceFile \
  -H "Authorization: Bearer <api_key>" \
  -F "Path=notes/todo.md" \
  -F "file=@todo.md"
response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "AddWorkspaceFile",
  "Data": { "Path": "notes/todo.md", "Size": 128 }
}

DeleteWorkspaceFile

Delete a workspace file (proxied to /_ksadk/workspace/v1/files/<path>).

POST /agentengine/api/v1/DeleteWorkspaceFile:

FieldTypeRequiredNotes
AgentIdstringnoTarget agent id (not currently enforced)
PathstringyesWorkspace-relative path
request.json
{ "Path": "notes/old.md" }
response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "DeleteWorkspaceFile",
  "Data": { "Deleted": true }
}

GetWorkspaceFileContent

Read workspace file content, returning the original content-type and disposition.

GET /agentengine/api/v1/GetWorkspaceFileContent?FilePath=...:

ParamTypeRequiredNotes
FilePathstringyesWorkspace-relative path
AgentIdstringnoTarget agent id (not currently enforced)
download-url
/agentengine/api/v1/GetWorkspaceFileContent?FilePath=notes/todo.md
binary
HTTP/1.1 200 OK
Content-Type: text/markdown
Content-Disposition: inline; filename="todo.md"

<file bytes>

HTML files are returned with an injected preview CSP so they can be embedded in the hosted UI preview pane.

ExportWorkspaceZip

Package the workspace (or a subdirectory) as a zip download.

GET /agentengine/api/v1/ExportWorkspaceZip:

ParamTypeRequiredNotes
PathstringnoWorkspace-relative directory, default .
AgentIdstringnoTarget agent id (not currently enforced)
download-url
/agentengine/api/v1/ExportWorkspaceZip?Path=.
binary
HTTP/1.1 200 OK
Content-Type: application/zip
Content-Disposition: attachment; filename="workspace.zip"

<zip bytes>

The filename is derived from Path: workspace.zip for the root, or workspace-<dir-with-dashes>.zip for a subdirectory. Symlinks and out-of-tree paths are skipped so the archive only contains regular files under the workspace root.

Models

ListAgentModels

List the available model catalog, including the current model and its source.

POST /agentengine/api/v1/ListAgentModels:

FieldTypeRequiredNotes
AgentIdstringnoTarget agent id (not currently used)
NamestringnoModel name filter (not currently used)
request.json
{}
response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "ListAgentModels",
  "Data": {
    "Models": [
      {
        "id": "glm-5.1",
        "display_name": "glm-5.1",
        "context_window_tokens": 128000,
        "max_output_tokens": 32000,
        "capabilities": {
          "multimodal_input_image": true,
          "multimodal_input_video": false,
          "multimodal_input_file": false
        },
        "limits": {
          "context_window_tokens": 128000,
          "max_input_tokens": 128000,
          "max_output_tokens": 32000,
          "max_reasoning_tokens": 8192,
          "rpm": 600,
          "tpm": 200000
        },
        "pricing": {},
        "auto_compact_threshold_tokens": 102400,
        "auto_compact_threshold_percentage": 0.8
      }
    ],
    "Current": "glm-5.1",
    "Source": "OPENAI_MODEL_NAME"
  }
}

Models element fields (normalized by normalize_model_metadata):

FieldNotes
id / display_nameModel id and display name
context_window_tokens / max_output_tokens / max_input_tokens / max_reasoning_tokensToken context limits
capabilitiesCapability set, including multimodal_input_image/video/file
limitsNormalized limits dict (rpm / tpm, etc.)
pricingPricing dict
auto_compact_threshold_tokens / _percentageAuto-compact thresholds

Current is the runtime's current model, and Source names the source env var (OPENAI_MODEL_NAME / MODEL_NAME / COZE_MODEL_NAME). The OpenAI-compatible GET /v1/models returns the same data with a different top-level envelope.

UI Bootstrap

GetAgentUiBootstrap

Returns the bootstrap metadata needed by the hosted UI for rendering and capability discovery. This is the first call the hosted UI makes on startup.

POST /agentengine/api/v1/GetAgentUiBootstrap:

FieldTypeRequiredNotes
AgentIdstringnoTarget agent id; defaults to the runtime agent name
SessionIdstringnoAssociated session (echoed back in the response)
request.json
{ "AgentId": "my-agent", "SessionId": "local-demo-session" }
response.json
{
  "Code": 0,
  "Message": "Success",
  "RequestId": "req_abc123",
  "Action": "GetAgentUiBootstrap",
  "Data": {
    "Agent": {
      "AgentId": "my-agent",
      "Name": "my-agent",
      "Description": "demo agent",
      "Framework": "langgraph"
    },
    "Modules": ["Chat", "Build", "Deploy"],
    "Capabilities": {
      "Attachments": true,
      "WorkspaceFiles": true,
      "Approval": true,
      "Thinking": true,
      "StopRun": true,
      "ResumeRun": true,
      "RuntimeCapabilities": { /* runner.get_runtime_capabilities() echoed verbatim */ },
      "CheckpointResumeCapability": {
        "Supported": true,
        "Checkpoint": {},
        "ResumeRun": {}
      },
      "RunLifecycle": {
        "Enabled": true,
        "Resume": true,
        "Abort": true,
        "Checkpoints": true,
        "CheckpointResume": true,
        "CheckpointResumePreview": true
      },
      "MCP": false,
      "HostedRuntime": false,
      "NativeTerminal": { "Enabled": false, "Mode": null, "Protocol": "ks-terminal.v1", "Path": null },
      "BuiltinTools": []
    },
    "WorkspaceFiles": { "Enabled": true },
    "AccessMode": "Owner",
    "SharePermissions": { "Interactive": true, "DefaultPath": "/chat", "SharePath": "/chat" },
    "CustomUI": {
      "Enabled": false,
      "Profile": null,
      "Path": null,
      "Url": null,
      "BundlePath": null
    },
    "ApiFormats": ["responses", "chat_completions"],
    "Stream": true,
    "SessionId": "local-demo-session",
    "SessionBackend": "memory",
    "HostedRuntime": null,
    "Model": { "id": "glm-5.1", "source": "OPENAI_MODEL_NAME", /* ... */ }
  }
}

Top-level Data fields:

FieldNotes
AgentAgent id / name / description / framework (from detection_result)
ModulesUI module list
CapabilitiesRuntime capability set, see table below
WorkspaceFilesWorkspace files bootstrap
AccessModeAccess mode, always Owner
SharePermissionsSharing and default paths
CustomUICustom UI resource info (0.6.7 normalized)
ApiFormatsSupported API shapes: responses, chat_completions
StreamWhether streaming is supported
SessionBackendSession backend description (memory / postgres, etc.)
ModelCurrent model metadata

Capabilities sub-fields:

FieldNotes
Attachments / WorkspaceFilesAttachment and workspace files capabilities
Approval / Thinking / StopRun / ResumeRunRun-control capabilities
RuntimeCapabilitiesCapability set returned verbatim by the runner (includes Checkpoint, ResumeRun, etc.)
CheckpointResumeCapability0.6.7 normalized: Supported + Checkpoint + ResumeRun detail
RunLifecycle0.6.7 normalized: run lifecycle semantics (Resume, Abort, Checkpoints, CheckpointResume, CheckpointResumePreview)
MCP / HostedRuntimePlatform capability flags, currently fixed false
NativeTerminalTerminal capability (Enabled / Mode / Protocol / Path)
BuiltinToolsBuiltin tool descriptions

CustomUI sub-fields (0.6.7):

FieldNotes
EnabledWhether custom UI is enabled
ProfileUI profile name
Path / UrlCustom UI path or external URL
BundlePathCustom UI bundle path

0.6.7 capability visibility

CheckpointResumeCapability and RunLifecycle are 0.6.7-normalized capability descriptors. Callers should use these to decide whether checkpoint/resume is available; if Supported is false or RunLifecycle.CheckpointResume is false, treat checkpoint/resume as unsupported.

Checkpoint and Resume Actions

New in 0.6.7

The four action paths below are allow-listed by the gateway Hosted UI filter, POST /agentengine/api/v1/*. Public API clients usually do not target these directly; prefer /v1/*.

ActionMethod and pathPurpose
ListSessionCheckpointsPOST /agentengine/api/v1/ListSessionCheckpointsList checkpoints under a session for resume selection
GetCheckpointResumePreviewPOST /agentengine/api/v1/GetCheckpointResumePreviewPreview the content and impact of resuming from a checkpoint
ResumeRunPOST /agentengine/api/v1/ResumeRunResume a run from a checkpoint
CancelRunPOST /agentengine/api/v1/CancelRunCancel an in-flight run

Capability visibility is governed by the RunLifecycle and RuntimeCapabilities (including CheckpointResumeCapability) returned by GetAgentUiBootstrap. If bootstrap does not declare the capability, callers should treat checkpoint/resume as unsupported.

ListSessionCheckpoints

POST /agentengine/api/v1/ListSessionCheckpoints:

FieldTypeRequiredNotes
AgentId / SessionIdstringyesSession location
RunIdstringnoFilter by run
FrameworkstringnoFilter by framework
OnlyResumableboolnoOnly return resumable checkpoints, default false
Offset / LimitintnoPagination, Limit range 1..500

Returns a Checkpoints array; each element includes RunId, CheckpointId, Framework, FrameworkRef, IsResumable, ResumeStatus, IsTerminal, CheckpointStatus, Backend, Scope, Durable, ResumeCount, ReplayAllowed, and ExpiresAt.

GetCheckpointResumePreview

POST /agentengine/api/v1/GetCheckpointResumePreview:

FieldTypeRequiredNotes
AgentId / SessionIdstringyesSession location
RunId / CheckpointIdstringyesCheckpoint location

Returns Preview containing Checkpoint, Capabilities, CanResume, Reason, NextNode, ExpectedAction, ToolReceipts, Risk (with Level and side-effect counts), and Summary.

ResumeRun

POST /agentengine/api/v1/ResumeRun:

FieldTypeRequiredNotes
AgentId / SessionIdstringyesSession location
RunId / CheckpointIdstringyesCheckpoint location
ResumeAttemptIdstringnoResume attempt id; runtime generates one when omitted
InvocationIdstringnoInvocation id passed through to the runner
Streamboolnotrue returns SSE
Model / ModelMetadata / ModelOptionsstring / objectnoModel parameter pass-through
ResumeInstructionEnabledboolno0.6.7 Whether to allow injecting a resume instruction
ResumeInstructionstringno0.6.7 resume instruction text

A terminal checkpoint returns status: "noop" rather than 409 to avoid blocking the UI. A non-terminal but non-resumable checkpoint returns 409.

GetAgentUiBootstrap

GetAgentUiBootstrap returns the bootstrap metadata for hosted UI rendering and capability discovery; the field table is in the UI Bootstrap section above.

Pagination Fields

ListSessions and ListSessionEvents support pagination but use different field names:

EndpointField groupFields
ListSessionspage-basedPage, PageSize, Total
ListSessionEventsoffset-basedOffset, Limit, Total
ListSessionCheckpointsoffset-basedOffset, Limit, Total

When resolving an ae-upload:// attachment, AttachmentContent uses the ae-upload:// prefix to locate hosted upload content and returns its byte stream; paths without that prefix are treated as workspace-relative paths.

RunAgent Pass-through Fields

RunAgent (hosted UI action) passes request-level model parameters through to the runner, just like /v1/responses and /v1/chat/completions:

FieldMeaning
ModelMetadataModel metadata, including reasoning, multimodal, context_window_tokens
ModelOptionsRequest-level model options (temperature, max_tokens, etc.)

ModelMetadata.reasoning flags reasoning mode, multimodal flags multimodal capability, and context_window_tokens flags the model context window size.

Workspace Files

Code-framework runtimes, and runtime products that enable the KsADK workspace surface, can all use the workspace routes.

  • List files.
  • Get file content or metadata.
  • Add or update a file.
  • Delete a file when allowed.
  • Export a workspace archive when supported.

The hosted UI download surfaces typically include:

  • GET /agentengine/api/v1/AttachmentContent
  • GET /agentengine/api/v1/GetWorkspaceFileContent
  • GET /agentengine/api/v1/ExportWorkspaceZip

All paths must be relative to the workspace root. Public examples must not expose host absolute paths.

Hermes-Specific Boundary

Hermes wraps its own dashboard and API server. The public docs only describe these surfaces:

SurfacePurpose
/Hermes dashboard
/v1/*Hermes API proxy surface
/_ksadk/workspace/v1/*KsADK workspace files
/_ksadk/terminal/wsterminal WebSocket

Terminal clients must use:

Sec-WebSocket-Protocol: ks-terminal.v1

OpenClaw-Specific Boundary

The upstream OpenClaw gateway owns its native routes. KsADK public docs only commit to the platform-supplemented contract:

SurfacePurpose
OpenClaw gateway rootOpenClaw native UI and API
/_ksadk/workspace/v1/*KsADK workspace files
health routeGateway liveness exposed by the runtime product

Do not write every upstream OpenClaw native endpoint as a KsADK contract unless it is implemented or stabilized by KsADK.

Streaming Output

Streaming calls use SSE:

Accept: text/event-stream

Clients should handle text deltas, tool events, errors, and completion events. LangGraph and ADK internal events may differ, but public clients should consume the runtime-normalized stream.

Public Doc Rules

Public examples must not include private endpoint hostnames, real API keys, gateway tokens, cookies, kdocs tokens, internal forwarded headers, kubeconfig paths, cluster names, private image registries, customer data, session ids, or workspace paths.

On this page