Co-authored-by: Vojtěch Biberle <vojtech.biberle@gmail.com> Co-authored-by: nova28 <17953305+nova28@users.noreply.github.com> Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
53 KiB
Kandev WebSocket API Reference
This document provides a complete reference for all WebSocket API actions, their payloads, responses, and usage patterns.
Overview
Kandev uses a single WebSocket connection for all API operations and real-time streaming. This eliminates the need for separate REST endpoints and enables full-duplex communication.
Endpoint: ws://localhost:38429/ws
Message Envelope
All messages follow this JSON envelope format:
{
"id": "uuid",
"type": "request|response|notification|error",
"action": "action.name",
"payload": {},
"timestamp": "2026-01-10T12:00:00Z"
}
| Field | Type | Description |
|---|---|---|
id |
string | UUID for request/response correlation. Omit for notifications. |
type |
string | Message type: request, response, notification, or error |
action |
string | The action to perform or that was performed |
payload |
object | Action-specific data |
timestamp |
string | ISO 8601 timestamp (optional) |
Error Response Format
{
"id": "correlation-uuid",
"type": "error",
"action": "original.action",
"payload": {
"code": "ERROR_CODE",
"message": "Human-readable message",
"details": {}
}
}
Error Codes:
BAD_REQUEST- Invalid message formatVALIDATION_ERROR- Missing or invalid fieldsNOT_FOUND- Resource not foundINTERNAL_ERROR- Server errorUNKNOWN_ACTION- Action not recognized
System Flow
flowchart LR
Client["Client (Browser)"] <-->|"WebSocket"| Server
subgraph Server["Kandev Server"]
Task["Task Service"]
Agent["Agent Manager"]
Orch["Orchestrator Service"]
Agent --> Docker["Docker Containers"]
end
Typical Workflow
- Connect to
ws://localhost:38429/ws - Create Board →
board.create - Create Column →
column.create - Create Task →
task.create - Subscribe to Task →
task.subscribe(receive real-time updates) - Start Execution →
orchestrator.start(launches agent) - Receive ACP Notifications ←
acp.progress,acp.log, etc. - Send Follow-up Prompts →
orchestrator.prompt(multi-turn) - Complete Task →
orchestrator.complete - Unsubscribe →
task.unsubscribe
Health Check
health.check
Purpose: Verify the WebSocket connection and server status.
Flow Position: Can be called at any time to verify connectivity.
Request:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "request",
"action": "health.check",
"payload": {}
}
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "response",
"action": "health.check",
"payload": {
"status": "ok",
"service": "kandev",
"mode": "unified"
}
}
| Response Field | Type | Description |
|---|---|---|
status |
string | Server health status (ok) |
service |
string | Service name |
mode |
string | API mode (unified = WebSocket-only) |
Workspace Actions
Workspaces are the top-level organizational unit that contain boards and repositories.
workspace.list
Purpose: List all workspaces.
Request:
{
"id": "uuid",
"type": "request",
"action": "workspace.list",
"payload": {}
}
Response:
{
"id": "uuid",
"type": "response",
"action": "workspace.list",
"payload": {
"workspaces": [
{
"id": "workspace-uuid",
"name": "My Project",
"description": "Main development workspace",
"owner_id": "user-uuid",
"created_at": "2026-01-10T12:00:00Z",
"updated_at": "2026-01-10T12:00:00Z"
}
]
}
}
workspace.create
Purpose: Create a new workspace.
Request:
{
"id": "uuid",
"type": "request",
"action": "workspace.create",
"payload": {
"name": "My Project",
"description": "Main development workspace",
"owner_id": "user-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
name |
string | ✅ | Workspace name (max 255 chars) |
description |
string | ❌ | Workspace description |
owner_id |
string | ❌ | Owner user ID |
Response: Created workspace object
workspace.get
Purpose: Get a workspace by ID.
Request:
{
"id": "uuid",
"type": "request",
"action": "workspace.get",
"payload": {
"id": "workspace-uuid"
}
}
Response: Workspace object
workspace.update
Purpose: Update a workspace.
Request:
{
"id": "uuid",
"type": "request",
"action": "workspace.update",
"payload": {
"id": "workspace-uuid",
"name": "Updated Name",
"description": "Updated description"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Workspace ID |
name |
string | ❌ | New name |
description |
string | ❌ | New description |
Response: Updated workspace object
workspace.delete
Purpose: Delete a workspace.
Request:
{
"id": "uuid",
"type": "request",
"action": "workspace.delete",
"payload": {
"id": "workspace-uuid"
}
}
Response:
{
"id": "uuid",
"type": "response",
"action": "workspace.delete",
"payload": {
"deleted": true
}
}
Board Actions
Boards are containers within workspaces that organize columns and tasks.
board.create
Purpose: Create a new Kanban board.
Flow Position: First step - create a board before adding columns and tasks.
Request:
{
"id": "uuid",
"type": "request",
"action": "board.create",
"payload": {
"name": "My Project",
"description": "Project description"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
name |
string | ✅ | Board name |
description |
string | ❌ | Optional description |
Response:
{
"id": "uuid",
"type": "response",
"action": "board.create",
"payload": {
"id": "board-uuid",
"name": "My Project",
"description": "Project description",
"created_at": "2026-01-10T12:00:00Z",
"updated_at": "2026-01-10T12:00:00Z"
}
}
board.list
Purpose: List all boards.
Flow Position: Use to display available boards to the user.
Request:
{
"id": "uuid",
"type": "request",
"action": "board.list",
"payload": {}
}
Response:
{
"id": "uuid",
"type": "response",
"action": "board.list",
"payload": {
"boards": [
{
"id": "board-uuid",
"name": "My Project",
"description": "...",
"created_at": "2026-01-10T12:00:00Z",
"updated_at": "2026-01-10T12:00:00Z"
}
],
"total": 1
}
}
board.get
Purpose: Get a specific board by ID.
Flow Position: Use to load board details before displaying columns and tasks.
Request:
{
"id": "uuid",
"type": "request",
"action": "board.get",
"payload": {
"id": "board-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Board ID |
Response:
{
"id": "uuid",
"type": "response",
"action": "board.get",
"payload": {
"id": "board-uuid",
"name": "My Project",
"description": "Project description",
"created_at": "2026-01-10T12:00:00Z",
"updated_at": "2026-01-10T12:00:00Z"
}
}
board.update
Purpose: Update an existing board's properties.
Flow Position: Use when user edits board name or description.
Request:
{
"id": "uuid",
"type": "request",
"action": "board.update",
"payload": {
"id": "board-uuid",
"name": "Updated Name",
"description": "Updated description"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Board ID |
name |
string | ❌ | New name (optional) |
description |
string | ❌ | New description (optional) |
Response: Same as board.get
board.delete
Purpose: Delete a board and all its columns and tasks.
Flow Position: Use with caution - this is destructive.
Request:
{
"id": "uuid",
"type": "request",
"action": "board.delete",
"payload": {
"id": "board-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Board ID |
Response:
{
"id": "uuid",
"type": "response",
"action": "board.delete",
"payload": {
"success": true
}
}
Column Actions
Columns organize tasks within a board and represent workflow states.
column.create
Purpose: Create a new column in a board.
Flow Position: After creating a board, create columns for workflow stages.
Request:
{
"id": "uuid",
"type": "request",
"action": "column.create",
"payload": {
"board_id": "board-uuid",
"name": "To Do",
"position": 0,
"state": "TODO"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
board_id |
string | ✅ | Parent board ID |
name |
string | ✅ | Column name |
position |
int | ❌ | Display order (0-indexed) |
state |
string | ❌ | Task state: TODO, IN_PROGRESS, DONE |
Response:
{
"id": "uuid",
"type": "response",
"action": "column.create",
"payload": {
"id": "column-uuid",
"board_id": "board-uuid",
"name": "To Do",
"position": 0,
"state": "TODO",
"created_at": "2026-01-10T12:00:00Z"
}
}
column.list
Purpose: List all columns in a board.
Flow Position: After loading a board, get its columns.
Request:
{
"id": "uuid",
"type": "request",
"action": "column.list",
"payload": {
"board_id": "board-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
board_id |
string | ✅ | Board ID |
Response:
{
"id": "uuid",
"type": "response",
"action": "column.list",
"payload": {
"columns": [
{
"id": "column-uuid",
"board_id": "board-uuid",
"name": "To Do",
"position": 0,
"state": "TODO",
"created_at": "2026-01-10T12:00:00Z"
}
],
"total": 1
}
}
column.get
Purpose: Get a specific column by ID.
Request:
{
"id": "uuid",
"type": "request",
"action": "column.get",
"payload": {
"id": "column-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Column ID |
Response: Same structure as items in column.list
Repository Actions
Repositories represent Git repositories linked to a workspace.
repository.list
Purpose: List all repositories in a workspace.
Request:
{
"id": "uuid",
"type": "request",
"action": "repository.list",
"payload": {
"workspace_id": "workspace-uuid"
}
}
Response:
{
"id": "uuid",
"type": "response",
"action": "repository.list",
"payload": {
"repositories": [
{
"id": "repo-uuid",
"workspace_id": "workspace-uuid",
"name": "my-project",
"source_type": "local",
"local_path": "/home/user/projects/my-project",
"provider": "",
"default_branch": "main",
"created_at": "2026-01-10T12:00:00Z",
"updated_at": "2026-01-10T12:00:00Z"
}
]
}
}
repository.create
Purpose: Create a new repository link.
Request:
{
"id": "uuid",
"type": "request",
"action": "repository.create",
"payload": {
"workspace_id": "workspace-uuid",
"name": "my-project",
"source_type": "local",
"local_path": "/home/user/projects/my-project",
"default_branch": "main",
"setup_script": "npm install",
"cleanup_script": "npm run clean"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
workspace_id |
string | ✅ | Workspace ID |
name |
string | ✅ | Repository name |
source_type |
string | ❌ | local or remote |
local_path |
string | ❌ | Local filesystem path |
provider |
string | ❌ | Git provider (github, gitlab, etc.) |
provider_repo_id |
string | ❌ | Provider's repository ID |
provider_owner |
string | ❌ | Repository owner on provider |
provider_name |
string | ❌ | Repository name on provider |
default_branch |
string | ❌ | Default branch name |
setup_script |
string | ❌ | Script to run on setup |
cleanup_script |
string | ❌ | Script to run on cleanup |
Response: Created repository object
repository.get
Purpose: Get a repository by ID.
Request:
{
"id": "uuid",
"type": "request",
"action": "repository.get",
"payload": {
"id": "repo-uuid"
}
}
Response: Repository object
repository.update
Purpose: Update a repository.
Request:
{
"id": "uuid",
"type": "request",
"action": "repository.update",
"payload": {
"id": "repo-uuid",
"name": "updated-name",
"default_branch": "develop"
}
}
Response: Updated repository object
repository.delete
Purpose: Delete a repository link.
Request:
{
"id": "uuid",
"type": "request",
"action": "repository.delete",
"payload": {
"id": "repo-uuid"
}
}
Response:
{
"id": "uuid",
"type": "response",
"action": "repository.delete",
"payload": {
"deleted": true
}
}
repository.script.list
Purpose: List scripts for a repository.
Request:
{
"id": "uuid",
"type": "request",
"action": "repository.script.list",
"payload": {
"repository_id": "repo-uuid"
}
}
Response:
{
"id": "uuid",
"type": "response",
"action": "repository.script.list",
"payload": {
"scripts": [
{
"id": "script-uuid",
"repository_id": "repo-uuid",
"name": "build",
"command": "npm run build",
"position": 0
}
]
}
}
repository.script.create
Purpose: Create a repository script.
Request:
{
"id": "uuid",
"type": "request",
"action": "repository.script.create",
"payload": {
"repository_id": "repo-uuid",
"name": "test",
"command": "npm test",
"position": 1
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
repository_id |
string | ✅ | Repository ID |
name |
string | ✅ | Script name |
command |
string | ✅ | Command to execute |
position |
int | ❌ | Order position |
Response: Created script object
repository.script.get
Purpose: Get a script by ID.
Request:
{
"id": "uuid",
"type": "request",
"action": "repository.script.get",
"payload": {
"id": "script-uuid"
}
}
Response: Script object
repository.script.update
Purpose: Update a script.
Request:
{
"id": "uuid",
"type": "request",
"action": "repository.script.update",
"payload": {
"id": "script-uuid",
"name": "updated-name",
"command": "npm run updated-command"
}
}
Response: Updated script object
repository.script.delete
Purpose: Delete a script.
Request:
{
"id": "uuid",
"type": "request",
"action": "repository.script.delete",
"payload": {
"id": "script-uuid"
}
}
Response:
{
"id": "uuid",
"type": "response",
"action": "repository.script.delete",
"payload": {
"deleted": true
}
}
Task Actions
Tasks are work items that can be executed by AI agents.
task.create
Purpose: Create a new task in a column.
Flow Position: Create tasks that agents will work on.
Request:
{
"id": "uuid",
"type": "request",
"action": "task.create",
"payload": {
"board_id": "board-uuid",
"column_id": "column-uuid",
"title": "Implement feature X",
"description": "Detailed requirements...",
"priority": 1,
"agent_type": "auggie",
"repository_url": "https://github.com/org/repo",
"branch": "main",
"metadata": {
"labels": ["feature", "priority-high"]
}
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
board_id |
string | ✅ | Board ID |
column_id |
string | ✅ | Column ID |
title |
string | ✅ | Task title |
description |
string | ❌ | Detailed description |
priority |
int | ❌ | Priority level (higher = more important) |
agent_type |
string | ❌ | Agent to use: auggie, gemini |
repository_url |
string | ❌ | Git repository URL |
branch |
string | ❌ | Git branch |
metadata |
object | ❌ | Custom key-value data |
Response:
{
"id": "uuid",
"type": "response",
"action": "task.create",
"payload": {
"id": "task-uuid",
"board_id": "board-uuid",
"column_id": "column-uuid",
"title": "Implement feature X",
"description": "Detailed requirements...",
"state": "TODO",
"priority": 1,
"agent_type": "auggie",
"repository_url": "https://github.com/org/repo",
"branch": "main",
"position": 0,
"created_at": "2026-01-10T12:00:00Z",
"updated_at": "2026-01-10T12:00:00Z",
"metadata": {}
}
}
| Response Field | Type | Description |
|---|---|---|
id |
string | Unique task ID |
state |
string | TODO, IN_PROGRESS, BLOCKED, COMPLETED, FAILED, CANCELLED |
position |
int | Position within column |
task.list
Purpose: List all tasks in a board.
Flow Position: Load tasks to display on the Kanban board.
Request:
{
"id": "uuid",
"type": "request",
"action": "task.list",
"payload": {
"board_id": "board-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
board_id |
string | ✅ | Board ID |
Response:
{
"id": "uuid",
"type": "response",
"action": "task.list",
"payload": {
"tasks": [ /* array of task objects */ ],
"total": 5
}
}
task.get
Purpose: Get a specific task by ID.
Request:
{
"id": "uuid",
"type": "request",
"action": "task.get",
"payload": {
"id": "task-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Task ID |
Response: Same structure as task.create response
task.update
Purpose: Update task properties (not state or position).
Request:
{
"id": "uuid",
"type": "request",
"action": "task.update",
"payload": {
"id": "task-uuid",
"title": "Updated title",
"description": "Updated description",
"priority": 2,
"metadata": { "key": "value" }
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Task ID |
title |
string | ❌ | New title |
description |
string | ❌ | New description |
priority |
int | ❌ | New priority |
metadata |
object | ❌ | Updated metadata |
Response: Updated task object
task.delete
Purpose: Delete a task.
Request:
{
"id": "uuid",
"type": "request",
"action": "task.delete",
"payload": {
"id": "task-uuid"
}
}
Response:
{
"id": "uuid",
"type": "response",
"action": "task.delete",
"payload": {
"success": true
}
}
task.move
Purpose: Move a task to a different column and/or position.
Flow Position: Use for drag-and-drop on Kanban board.
Request:
{
"id": "uuid",
"type": "request",
"action": "task.move",
"payload": {
"id": "task-uuid",
"column_id": "target-column-uuid",
"position": 0
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Task ID |
column_id |
string | ✅ | Target column ID |
position |
int | ❌ | Position in column (0-indexed) |
Response: Updated task object with new column_id and position
task.state
Purpose: Update a task's state directly.
Flow Position: Used by orchestrator to update task state during execution.
Request:
{
"id": "uuid",
"type": "request",
"action": "task.state",
"payload": {
"id": "task-uuid",
"state": "IN_PROGRESS"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Task ID |
state |
string | ✅ | New state: CREATED, SCHEDULING, TODO, IN_PROGRESS, REVIEW, BLOCKED, WAITING_FOR_INPUT, COMPLETED, FAILED, CANCELLED |
Response: Updated task object
Task Subscription Actions
Subscriptions enable real-time streaming of agent output (ACP) to specific clients.
task.subscribe
Purpose: Subscribe to receive real-time notifications for a specific task.
Flow Position: Call before orchestrator.start to receive agent output.
Request:
{
"id": "uuid",
"type": "request",
"action": "task.subscribe",
"payload": {
"task_id": "task-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
task_id |
string | ✅ | Task ID to subscribe to |
Response:
{
"id": "uuid",
"type": "response",
"action": "task.subscribe",
"payload": {
"success": true,
"task_id": "task-uuid"
}
}
Effect: After subscribing, you will receive notifications for this task:
acp.progress- Progress updatesacp.log- Agent log messagesacp.result- Agent resultsacp.error- Agent errorstask.created- Task createdtask.updated- Task properties changedtask.deleted- Task deletedtask.state_changed- Task state changed
task.unsubscribe
Purpose: Stop receiving notifications for a task.
Flow Position: Call after task completes or when navigating away.
Request:
{
"id": "uuid",
"type": "request",
"action": "task.unsubscribe",
"payload": {
"task_id": "task-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
task_id |
string | ✅ | Task ID to unsubscribe from |
Response:
{
"id": "uuid",
"type": "response",
"action": "task.unsubscribe",
"payload": {
"success": true,
"task_id": "task-uuid"
}
}
Comment Actions
Comments enable conversation between users and agents on tasks.
comment.add
Purpose: Add a comment to a task. If an agent is running on the task, the comment is automatically forwarded as a prompt.
Request:
{
"id": "uuid",
"type": "request",
"action": "comment.add",
"payload": {
"task_id": "task-uuid",
"content": "Please also add unit tests for the new function",
"author_id": "user-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
task_id |
string | ✅ | Task ID |
content |
string | ✅ | Comment text |
author_id |
string | ❌ | Author user ID |
Response:
{
"id": "uuid",
"type": "response",
"action": "comment.add",
"payload": {
"id": "comment-uuid",
"task_id": "task-uuid",
"author_type": "user",
"author_id": "user-uuid",
"content": "Please also add unit tests for the new function",
"requests_input": false,
"created_at": "2026-01-10T12:00:00Z"
}
}
comment.list
Purpose: List all comments for a task.
Request:
{
"id": "uuid",
"type": "request",
"action": "comment.list",
"payload": {
"task_id": "task-uuid"
}
}
Response:
{
"id": "uuid",
"type": "response",
"action": "comment.list",
"payload": {
"comments": [
{
"id": "comment-uuid-1",
"task_id": "task-uuid",
"author_type": "user",
"author_id": "user-uuid",
"content": "Please implement the login feature",
"requests_input": false,
"created_at": "2026-01-10T12:00:00Z"
},
{
"id": "comment-uuid-2",
"task_id": "task-uuid",
"author_type": "agent",
"author_id": "agent-instance-uuid",
"content": "I've implemented the login feature. Should I also add password reset?",
"requests_input": true,
"created_at": "2026-01-10T12:05:00Z"
}
]
}
}
| Response Field | Type | Description |
|---|---|---|
author_type |
string | user or agent |
requests_input |
boolean | True if agent is asking for user input |
Agent Actions
Agents are Docker containers running AI coding assistants.
agent.list
Purpose: List all agent instances (running and completed).
Request:
{
"id": "uuid",
"type": "request",
"action": "agent.list",
"payload": {}
}
Response:
{
"id": "uuid",
"type": "response",
"action": "agent.list",
"payload": {
"agents": [
{
"id": "agent-uuid",
"task_id": "task-uuid",
"agent_type": "auggie",
"container_id": "docker-container-id",
"status": "running",
"progress": 45,
"started_at": "2026-01-10T12:00:00Z",
"finished_at": null,
"exit_code": null,
"error": null
}
],
"total": 1
}
}
| Response Field | Type | Description |
|---|---|---|
status |
string | starting, running, completed, failed, stopped, READY |
progress |
int | 0-100 percentage |
exit_code |
int | Container exit code (when completed) |
error |
string | Error message (if failed) |
agent.launch
Purpose: Launch an agent container directly (low-level).
Flow Position: Typically use orchestrator.start instead, which handles this automatically.
Request:
{
"id": "uuid",
"type": "request",
"action": "agent.launch",
"payload": {
"task_id": "task-uuid",
"agent_type": "auggie",
"workspace_path": "/path/to/workspace",
"env": {
"CUSTOM_VAR": "value"
}
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
task_id |
string | ✅ | Task ID this agent is for |
agent_type |
string | ✅ | Agent type: auggie, gemini |
workspace_path |
string | ✅ | Path to mount in container |
env |
object | ❌ | Additional environment variables |
Response:
{
"id": "uuid",
"type": "response",
"action": "agent.launch",
"payload": {
"success": true,
"agent_id": "agent-uuid",
"task_id": "task-uuid"
}
}
agent.status
Purpose: Get detailed status of a specific agent.
Request:
{
"id": "uuid",
"type": "request",
"action": "agent.status",
"payload": {
"agent_id": "agent-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
agent_id |
string | ✅ | Agent instance ID |
Response:
{
"id": "uuid",
"type": "response",
"action": "agent.status",
"payload": {
"id": "agent-uuid",
"task_id": "task-uuid",
"agent_type": "auggie",
"container_id": "docker-container-id",
"status": "running",
"progress": 67,
"started_at": "2026-01-10T12:00:00Z",
"finished_at": null,
"exit_code": null,
"error": null
}
}
agent.logs
Purpose: Get agent container logs.
Request:
{
"id": "uuid",
"type": "request",
"action": "agent.logs",
"payload": {
"agent_id": "agent-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
agent_id |
string | ✅ | Agent instance ID |
Response:
{
"id": "uuid",
"type": "response",
"action": "agent.logs",
"payload": {
"agent_id": "agent-uuid",
"logs": ["log line 1", "log line 2"],
"message": "..."
}
}
agent.stop
Purpose: Stop a running agent container.
Request:
{
"id": "uuid",
"type": "request",
"action": "agent.stop",
"payload": {
"agent_id": "agent-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
agent_id |
string | ✅ | Agent instance ID |
Response:
{
"id": "uuid",
"type": "response",
"action": "agent.stop",
"payload": {
"success": true
}
}
agent.types
Purpose: List available agent types.
Request:
{
"id": "uuid",
"type": "request",
"action": "agent.types",
"payload": {}
}
Response:
{
"id": "uuid",
"type": "response",
"action": "agent.types",
"payload": {
"types": [
{
"id": "auggie",
"name": "Auggie CLI Agent",
"description": "Augment Code CLI-based coding agent",
"image": "ghcr.io/kandev/auggie-agent:latest",
"capabilities": ["code-generation", "refactoring", "testing"],
"enabled": true
},
{
"id": "gemini",
"name": "Gemini Agent",
"description": "Google Gemini-based coding agent",
"image": "ghcr.io/kandev/gemini-agent:latest",
"capabilities": ["code-generation", "analysis"],
"enabled": true
}
],
"total": 2
}
}
Orchestrator Actions
The orchestrator coordinates task execution, managing the workflow between tasks and agents.
orchestrator.status
Purpose: Get overall orchestrator status.
Request:
{
"id": "uuid",
"type": "request",
"action": "orchestrator.status",
"payload": {}
}
Response:
{
"id": "uuid",
"type": "response",
"action": "orchestrator.status",
"payload": {
"running": true,
"active_tasks": 2,
"queued_tasks": 5,
"max_concurrent": 3
}
}
orchestrator.queue
Purpose: Get the current task queue.
Request:
{
"id": "uuid",
"type": "request",
"action": "orchestrator.queue",
"payload": {}
}
Response:
{
"id": "uuid",
"type": "response",
"action": "orchestrator.queue",
"payload": {
"tasks": [
{
"task_id": "task-uuid",
"priority": 1,
"queued_at": "2026-01-10T12:00:00Z"
}
],
"total": 1
}
}
orchestrator.trigger
Purpose: Trigger a task for execution (adds to queue).
Request:
{
"id": "uuid",
"type": "request",
"action": "orchestrator.trigger",
"payload": {
"task_id": "task-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
task_id |
string | ✅ | Task ID to trigger |
Response:
{
"id": "uuid",
"type": "response",
"action": "orchestrator.trigger",
"payload": {
"success": true,
"message": "Task triggered",
"task_id": "task-uuid"
}
}
orchestrator.start
Purpose: Start executing a task immediately with an agent.
Flow Position: Main action to begin agent work on a task.
Request:
{
"id": "uuid",
"type": "request",
"action": "orchestrator.start",
"payload": {
"task_id": "task-uuid",
"agent_type": "auggie",
"priority": 1
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
task_id |
string | ✅ | Task ID to start |
agent_type |
string | ❌ | Override default agent type |
priority |
int | ❌ | Execution priority |
Response:
{
"id": "uuid",
"type": "response",
"action": "orchestrator.start",
"payload": {
"success": true,
"task_id": "task-uuid",
"agent_instance_id": "agent-uuid",
"status": "running"
}
}
Effect:
- Task state changes to
IN_PROGRESS - Agent container is launched
- ACP notifications begin streaming (if subscribed)
orchestrator.stop
Purpose: Stop a running task execution.
Request:
{
"id": "uuid",
"type": "request",
"action": "orchestrator.stop",
"payload": {
"task_id": "task-uuid",
"reason": "User cancelled",
"force": false
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
task_id |
string | ✅ | Task ID to stop |
reason |
string | ❌ | Reason for stopping |
force |
bool | ❌ | Force kill (default: false) |
Response:
{
"id": "uuid",
"type": "response",
"action": "orchestrator.stop",
"payload": {
"success": true
}
}
orchestrator.prompt
Purpose: Send a follow-up prompt to a running agent (multi-turn conversation).
Flow Position: Use during agent execution for clarifications or additional instructions.
Request:
{
"id": "uuid",
"type": "request",
"action": "orchestrator.prompt",
"payload": {
"task_id": "task-uuid",
"prompt": "Also add unit tests for the new function"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
task_id |
string | ✅ | Task ID (must have running agent) |
prompt |
string | ✅ | Follow-up prompt text |
Response:
{
"id": "uuid",
"type": "response",
"action": "orchestrator.prompt",
"payload": {
"success": true
}
}
Effect: The prompt is sent to the agent via agentctl HTTP sidecar.
orchestrator.complete
Purpose: Mark a task as completed.
Flow Position: Called when agent finishes successfully or user approves the work.
Request:
{
"id": "uuid",
"type": "request",
"action": "orchestrator.complete",
"payload": {
"task_id": "task-uuid"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
task_id |
string | ✅ | Task ID to complete |
Response:
{
"id": "uuid",
"type": "response",
"action": "orchestrator.complete",
"payload": {
"success": true,
"message": "task completed"
}
}
Session Actions
Session lifecycle is managed idempotently: clients ask the backend to ensure a session exists for a task, and the backend resolves the agent profile and decides whether to prepare or start the agent.
session.ensure
Purpose: Ensure a task has at least one session, creating one if needed.
Idempotent: returns the task's existing primary (or newest) session when one
already exists. The backend resolves the agent profile from task metadata,
workflow step, workflow, or workspace default, and chooses prepare vs
start based on the workflow step's auto_start_agent action unless the
client overrides it with auto_start.
Flow Position: Called when opening a task so the chat has a session to attach to.
Request:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "request",
"action": "session.ensure",
"payload": {
"task_id": "task-uuid",
"auto_start": false
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
task_id |
string | ✅ | Task to ensure a session for |
auto_start |
boolean | ❌ | Optional override of the workflow step's auto-start decision. false prepares the session (created_prepare) without launching the agent; true forces a start (created_start). Omitting it defers to the workflow step's auto_start_agent action. |
Response:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "response",
"action": "session.ensure",
"payload": {
"success": true,
"task_id": "task-uuid",
"session_id": "session-uuid",
"state": "CREATED",
"agent_profile_id": "profile-uuid",
"source": "created_prepare",
"newly_created": true
}
}
| Response Field | Type | Description |
|---|---|---|
success |
boolean | Whether the ensure succeeded |
task_id |
string | The task the session belongs to |
session_id |
string | The ensured session |
state |
string | Session state (CREATED for a prepared session, STARTING/RUNNING when the agent is launching) |
agent_profile_id |
string | Resolved agent profile |
source |
string | Where the session came from: existing_primary, existing_newest, created_prepare, or created_start |
newly_created |
boolean | Whether the session was created by this call |
workspace_path |
string | Worktree path (present when a workspace was prepared) |
Effect: With auto_start: false the agent stays stopped and the client
shows a manual "Start agent" affordance; with auto_start: true (or the
workflow step's auto_start_agent action) the agent launches immediately.
Permission Actions
Agents may request user permission for certain operations. The permission flow uses notifications and responses.
permission.requested (Notification)
Purpose: Server notifies client that an agent is requesting permission.
When: Agent calls a tool that requires user approval.
{
"type": "notification",
"action": "permission.requested",
"payload": {
"task_id": "task-uuid",
"request_id": "kandev-request-uuid",
"pending_id": "pending-request-uuid",
"instance_id": "agent-instance-uuid",
"session_id": "task-session-uuid",
"tool_call_id": "tool-call-uuid",
"title": "Execute shell command",
"description": "Agent wants to run: npm install express",
"options": [
{
"option_id": "allow-once",
"name": "Allow Once",
"kind": "allow_once"
},
{
"option_id": "allow-always",
"name": "Always Allow",
"kind": "allow_always"
},
{
"option_id": "reject-once",
"name": "Deny",
"kind": "reject_once"
}
],
"created_at": "2026-01-10T12:00:00Z"
},
"timestamp": "2026-01-10T12:00:00Z"
}
| Payload Field | Type | Description |
|---|---|---|
task_id |
string | Task the agent is working on |
request_id |
string | Kandev request-generation ID; changes when a provider request is replaced |
pending_id |
string | Unique ID for this pending request |
instance_id |
string | Agent instance ID |
session_id |
string | Kandev task session ID |
tool_call_id |
string | Tool call requesting permission |
title |
string | Human-readable title |
description |
string | Additional context |
options |
array | Available permission choices |
Option Kinds:
allow_once- Allow this specific actionallow_always- Allow this type of action permanentlyreject_once- Deny this specific actionreject_always- Deny this type of action permanently
permission.respond
Purpose: User responds to a permission request.
Request:
{
"id": "uuid",
"type": "request",
"action": "permission.respond",
"payload": {
"task_id": "task-uuid",
"session_id": "task-session-uuid",
"request_id": "kandev-request-uuid",
"pending_id": "pending-request-uuid",
"option_id": "allow-once"
}
}
| Payload Field | Type | Required | Description |
|---|---|---|---|
task_id |
string | ✅ | Task ID |
session_id |
string | ✅ | Kandev task session ID belonging to the task |
request_id |
string | ✅ | Exact request-generation ID from the permission message |
pending_id |
string | ✅ | Pending request ID from notification |
option_id |
string | ❌ | Selected option ID (required if not cancelled) |
cancelled |
boolean | ❌ | True to cancel the request |
rejected |
boolean | ❌ | Compatibility status hint; the selected provider option kind remains authoritative |
Response:
{
"id": "uuid",
"type": "response",
"action": "permission.respond",
"payload": {
"success": true,
"session_id": "task-session-uuid",
"pending_id": "pending-request-uuid"
}
}
Error Response (stale or replaced request):
{
"id": "uuid",
"type": "error",
"action": "permission.respond",
"payload": {
"code": "INTERNAL_ERROR",
"message": "Failed to respond to permission: permission_stale"
}
}
Server Notifications (ACP Streaming)
These are push notifications from the server to subscribed clients. They have type: "notification" and no id field.
acp.progress
Purpose: Agent progress update.
When: Periodically during agent execution.
{
"type": "notification",
"action": "acp.progress",
"payload": {
"task_id": "task-uuid",
"agent_id": "agent-uuid",
"progress": 45,
"message": "Analyzing code structure...",
"current_file": "src/main.go",
"files_processed": 12,
"total_files": 27
},
"timestamp": "2026-01-10T12:05:00Z"
}
acp.log
Purpose: Agent log message (debug, info, warn, error).
When: As agent produces output.
{
"type": "notification",
"action": "acp.log",
"payload": {
"task_id": "task-uuid",
"agent_id": "agent-uuid",
"level": "info",
"message": "Starting code generation for feature X",
"metadata": {
"component": "code-generator"
}
},
"timestamp": "2026-01-10T12:05:30Z"
}
| Payload Field | Type | Description |
|---|---|---|
level |
string | debug, info, warn, error |
acp.result
Purpose: Agent produced a result artifact.
When: Agent completes a unit of work.
{
"type": "notification",
"action": "acp.result",
"payload": {
"task_id": "task-uuid",
"agent_id": "agent-uuid",
"status": "success",
"summary": "Created 3 new files",
"artifacts": [
{ "type": "file", "path": "src/feature.go" },
{ "type": "file", "path": "src/feature_test.go" }
]
},
"timestamp": "2026-01-10T12:10:00Z"
}
acp.error
Purpose: Agent encountered an error.
When: Error during agent execution.
{
"type": "notification",
"action": "acp.error",
"payload": {
"task_id": "task-uuid",
"agent_id": "agent-uuid",
"code": "COMPILE_ERROR",
"message": "Failed to compile: syntax error",
"details": {
"file": "src/main.go",
"line": 42
}
},
"timestamp": "2026-01-10T12:06:00Z"
}
acp.status
Purpose: Agent status changed.
When: Agent starts, completes, or fails.
{
"type": "notification",
"action": "acp.status",
"payload": {
"task_id": "task-uuid",
"agent_id": "agent-uuid",
"status": "completed",
"previous_status": "running",
"exit_code": 0
},
"timestamp": "2026-01-10T12:15:00Z"
}
acp.heartbeat
Purpose: Keep-alive signal from agent.
When: Periodically while agent is running (prevents timeout).
{
"type": "notification",
"action": "acp.heartbeat",
"payload": {
"task_id": "task-uuid",
"agent_id": "agent-uuid"
},
"timestamp": "2026-01-10T12:05:00Z"
}
comment.added
Purpose: New comment added to a task.
When: User or agent adds a comment.
{
"type": "notification",
"action": "comment.added",
"payload": {
"task_id": "task-uuid",
"comment_id": "comment-uuid",
"author_type": "agent",
"author_id": "agent-instance-uuid",
"content": "I've completed the implementation. Would you like me to add tests?",
"requests_input": true,
"created_at": "2026-01-10T12:05:00Z"
},
"timestamp": "2026-01-10T12:05:00Z"
}
| Payload Field | Type | Description |
|---|---|---|
author_type |
string | user or agent |
requests_input |
boolean | True if agent is asking for user input |
task.updated
Purpose: Task properties changed.
When: Task state, title, or other properties change.
{
"type": "notification",
"action": "task.updated",
"payload": {
"task_id": "task-uuid",
"board_id": "board-uuid",
"column_id": "column-uuid",
"title": "Implement user authentication",
"description": "Add JWT validation and refresh tokens",
"state": "IN_PROGRESS",
"priority": 2,
"position": 1,
"created_at": "2026-01-10T12:00:00Z",
"updated_at": "2026-01-10T12:05:00Z"
},
"timestamp": "2026-01-10T12:00:05Z"
}
task.created
Purpose: Task created.
{
"type": "notification",
"action": "task.created",
"payload": {
"task_id": "task-uuid",
"board_id": "board-uuid",
"column_id": "column-uuid",
"title": "Implement user authentication",
"description": "Add JWT validation and refresh tokens",
"state": "CREATED",
"priority": 2,
"position": 0,
"created_at": "2026-01-10T12:00:00Z",
"updated_at": "2026-01-10T12:00:00Z"
},
"timestamp": "2026-01-10T12:00:00Z"
}
task.deleted
Purpose: Task deleted.
{
"type": "notification",
"action": "task.deleted",
"payload": {
"task_id": "task-uuid",
"board_id": "board-uuid",
"column_id": "column-uuid",
"title": "Implement user authentication"
},
"timestamp": "2026-01-10T12:30:00Z"
}
task.state_changed
Purpose: Task state changed.
{
"type": "notification",
"action": "task.state_changed",
"payload": {
"task_id": "task-uuid",
"board_id": "board-uuid",
"column_id": "column-uuid",
"title": "Implement user authentication",
"state": "IN_PROGRESS",
"old_state": "TODO",
"new_state": "IN_PROGRESS",
"updated_at": "2026-01-10T12:10:00Z"
},
"timestamp": "2026-01-10T12:10:00Z"
}
workspace.created / workspace.updated / workspace.deleted
Purpose: Workspace lifecycle notifications.
{
"type": "notification",
"action": "workspace.updated",
"payload": {
"id": "workspace-uuid",
"name": "Kandev",
"description": "Primary workspace",
"owner_id": "user-uuid",
"created_at": "2026-01-10T12:00:00Z",
"updated_at": "2026-01-10T12:20:00Z"
},
"timestamp": "2026-01-10T12:20:00Z"
}
board.created / board.updated / board.deleted
Purpose: Board lifecycle notifications.
{
"type": "notification",
"action": "board.updated",
"payload": {
"id": "board-uuid",
"workspace_id": "workspace-uuid",
"name": "Dev",
"description": "Default board",
"created_at": "2026-01-10T12:00:00Z",
"updated_at": "2026-01-10T12:25:00Z"
},
"timestamp": "2026-01-10T12:25:00Z"
}
column.created / column.updated / column.deleted
Purpose: Column lifecycle notifications.
{
"type": "notification",
"action": "column.updated",
"payload": {
"id": "column-uuid",
"board_id": "board-uuid",
"name": "In Progress",
"position": 1,
"state": "IN_PROGRESS",
"color": "bg-blue-500",
"created_at": "2026-01-10T12:00:00Z",
"updated_at": "2026-01-10T12:30:00Z"
},
"timestamp": "2026-01-10T12:30:00Z"
}
repository.created / repository.updated / repository.deleted
Purpose: Repository lifecycle notifications.
{
"type": "notification",
"action": "repository.updated",
"payload": {
"id": "repo-uuid",
"workspace_id": "workspace-uuid",
"name": "kandev",
"source_type": "local",
"local_path": "/home/user/Projects/kandev",
"provider": "",
"default_branch": "main",
"updated_at": "2026-01-10T12:40:00Z"
},
"timestamp": "2026-01-10T12:40:00Z"
}
repository.script.created / repository.script.updated / repository.script.deleted
Purpose: Repository script lifecycle notifications.
{
"type": "notification",
"action": "repository.script.updated",
"payload": {
"id": "script-uuid",
"repository_id": "repo-uuid",
"name": "Setup",
"command": "npm install",
"position": 0,
"updated_at": "2026-01-10T12:45:00Z"
},
"timestamp": "2026-01-10T12:45:00Z"
}
agent.updated
Purpose: Agent status changed.
When: Agent starts, stops, or changes state.
{
"type": "notification",
"action": "agent.updated",
"payload": {
"id": "agent-uuid",
"task_id": "task-uuid",
"status": "running",
"progress": 0
},
"timestamp": "2026-01-10T12:00:03Z"
}
Complete Usage Example
const ws = new WebSocket('ws://localhost:38429/ws');
const pending = new Map();
// Handle incoming messages
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === 'response' || msg.type === 'error') {
// Resolve pending request
const resolve = pending.get(msg.id);
if (resolve) {
pending.delete(msg.id);
resolve(msg);
}
} else if (msg.type === 'notification') {
// Handle real-time updates
console.log(`[${msg.action}]`, msg.payload);
}
};
// Helper to send requests
function request(action, payload) {
return new Promise((resolve) => {
const id = crypto.randomUUID();
pending.set(id, resolve);
ws.send(JSON.stringify({ id, type: 'request', action, payload }));
});
}
// Full workflow example
async function runTask() {
// 1. Create board
const board = await request('board.create', { name: 'My Project' });
// 2. Create column
const column = await request('column.create', {
board_id: board.payload.id,
name: 'To Do',
state: 'TODO'
});
// 3. Create task
const task = await request('task.create', {
board_id: board.payload.id,
column_id: column.payload.id,
title: 'Implement user authentication',
agent_type: 'auggie'
});
// 4. Subscribe to updates
await request('task.subscribe', { task_id: task.payload.id });
// 5. Start execution
await request('orchestrator.start', { task_id: task.payload.id });
// 6. ACP notifications will now stream automatically...
// 7. Send follow-up prompt (optional)
await request('orchestrator.prompt', {
task_id: task.payload.id,
prompt: 'Also add JWT token validation'
});
// 8. When done, complete the task
await request('orchestrator.complete', { task_id: task.payload.id });
// 9. Unsubscribe
await request('task.unsubscribe', { task_id: task.payload.id });
}
Quick Reference
Request Actions
| Action | Purpose |
|---|---|
health.check |
Server health status |
| Workspace | |
workspace.list |
List all workspaces |
workspace.create |
Create workspace |
workspace.get |
Get workspace by ID |
workspace.update |
Update workspace |
workspace.delete |
Delete workspace |
| Board | |
board.create |
Create board |
board.list |
List all boards |
board.get |
Get board by ID |
board.update |
Update board |
board.delete |
Delete board |
| Column | |
column.create |
Create column |
column.list |
List columns in board |
column.get |
Get column by ID |
column.update |
Update column |
column.delete |
Delete column |
| Repository | |
repository.list |
List repositories in workspace |
repository.create |
Create repository link |
repository.get |
Get repository by ID |
repository.update |
Update repository |
repository.delete |
Delete repository |
repository.script.list |
List repository scripts |
repository.script.create |
Create script |
repository.script.get |
Get script by ID |
repository.script.update |
Update script |
repository.script.delete |
Delete script |
| Task | |
task.create |
Create task |
task.list |
List tasks in board |
task.get |
Get task by ID |
task.update |
Update task properties |
task.delete |
Delete task |
task.move |
Move task to column/position |
task.state |
Change task state |
task.subscribe |
Subscribe to task notifications |
task.unsubscribe |
Unsubscribe from task |
| Comment | |
comment.add |
Add comment to task |
comment.list |
List comments for task |
| Agent | |
agent.list |
List agent instances |
agent.launch |
Launch agent (low-level) |
agent.status |
Get agent status |
agent.logs |
Get agent logs |
agent.stop |
Stop agent |
agent.types |
List available agent types |
| Orchestrator | |
orchestrator.status |
Get orchestrator status |
orchestrator.queue |
Get task queue |
orchestrator.trigger |
Queue task for execution |
orchestrator.start |
Start task execution |
orchestrator.stop |
Stop task execution |
orchestrator.prompt |
Send follow-up prompt |
orchestrator.complete |
Complete task |
| Permission | |
permission.respond |
Respond to permission request |
Notification Actions (Server → Client)
| Action | Purpose |
|---|---|
acp.progress |
Agent progress update |
acp.log |
Agent log message |
acp.result |
Agent result artifact |
acp.error |
Agent error |
acp.status |
Agent status change |
acp.heartbeat |
Keep-alive heartbeat |
permission.requested |
Agent requesting permission |
comment.added |
New comment on task |
task.updated |
Task was updated |
task.created |
Task was created |
task.deleted |
Task was deleted |
workspace.created |
Workspace was created |
workspace.updated |
Workspace was updated |
workspace.deleted |
Workspace was deleted |
board.created |
Board was created |
board.updated |
Board was updated |
board.deleted |
Board was deleted |
column.created |
Column was created |
column.updated |
Column was updated |
column.deleted |
Column was deleted |