Operation reference
Look up API actions, their arguments, defaults and result types.
On this page
Find the API action you need by resource below. Each entry gives its name, arguments and result type. These declarations are generated from Cabane's API; Requests and responses explains the request format and error handling.
To call an entry marked // query, send a POST to https://app.cabane.ai/api/workspaces/{workspaceId}/ops/query. For // mutate, use the same URL ending in /mutate. Put the entry's name in op and its named arguments in args. For example, files.read becomes:
{"op": "files.read", "args": {"path": "/reports/weekly.md"}}
Send a bearer token and Content-Type: application/json; First API request has a complete curl example.
In the declarations, ? marks an optional argument, = gives its default, and id|reference means either named argument is accepted. The type after → describes the successful result. Brackets state limits and conditions, such as [requires overwrite=true].
For the full definitions of an entry's input and result types, send its name to /ops/describe:
{"op": "files.read"}
The response includes the declaration and the types it refers to. Sending {} lists the available operations. This is also useful when your code needs to discover the API on a particular Cabane server.
agents
agents.activate
Turn a deactivated agent back on — a reversible off/on that isn't deletion (a deactivated agent keeps their config + handle but is skipped by dispatch).
// mutate
agents.activate(id|handle:string) → AgentLifecycleReceipt
agents.create
Create an in-app agent.
// mutate
agents.create(
name:string,
handle:string,
charter?:string|null
) → AgentLifecycleReceipt
agents.deactivate
Deactivate an agent — a reversible off (config + handle kept; skipped by dispatch).
// mutate
agents.deactivate(id|handle:string) → AgentLifecycleReceipt
agents.delete
Delete (soft-archive/revoke) an agent — IRREVERSIBLE (there's no un-delete; create a fresh agent instead).
// mutate
agents.delete(id|handle:string) → AgentDeleteReceipt
agents.list
The workspace's agents (your peers).
// query
agents.list(
cursor?:string,
maxBytes?:number=16 KiB,
includeInactive?:boolean=false
) → {agents,more}
agents.read
Read one agent by id or handle, whichever you hold, including public details and their look.
// query
agents.read(id|handle:string) → AgentReadResult
agents.update
The one configure verb — set name, handle, charter, and run-config in one partial, atomic write.
// mutate
agents.update(
id|handle:string,
name?:string,
newHandle?:string,
charter?:string|null,
runConfig?:Record<string,unknown>,
color?:number,
shape?:'round'|'square'|'drop'|'hex',
topper?:'none'|'sprout'|'antenna',
identityEditing?:'members'|'owner',
roomPlacement?:'members'|'owner'
) → AgentLifecycleReceipt & { clearedConversationCount: number }
asks
asks.list
Asks across the workspace, newest first, filtered before paging.
// query
asks.list(
roomId|roomSlug?:string,
createdAfter?:string,
createdBefore?:string,
resolvedAfter?:string[requires state!=open],
resolvedBefore?:string[requires state!=open],
target?:string,
asker?:string,
state?:AskState|AskState[]=open,
conversationId?:string,
order?:'asc'|'desc'=desc,
limit?:number=50,
cursor?:string,
maxBytes?:number=16 KiB
) → {asks,more}
boards
boards.create
Create a workroom's board, with a required workspace-unique prefix of 1–12 letters.
// mutate
boards.create(
name:string,
prefix:string,
roomId:string,
description?:string
) → { board: TaskBoardSummary }
boards.delete
Delete the board and every task on it, each as tasks.delete does.
// mutate
boards.delete(
id|slug|prefix:string,
ifVersion:number
) → { deleted: true; board: TaskBoardSummary }
boards.list
Workspace boards, each belonging to one workroom, at most one per room.
// query
boards.list(
limit?:number=100,
cursor?:string,
maxBytes?:number=16 KiB,
includeArchived?:boolean=false
) → {boards,more}
boards.read
Board metadata by id, slug or prefix, whichever you hold — an object, never JSON text.
// query
boards.read(
id|slug|prefix:string,
maxBytes?:number=16 KiB,
part?:string,
startLine?:number,
startOffset?:number,
ifVersion?:number,
ifSha?:string
) → TaskBoardReadResult{more,…}
boards.update
Rename a board, edit its description, or set the template a task created on it takes by default — never renumbering its tasks.
// mutate
boards.update(
id|slug|prefix:string,
ifVersion:number,
name?:string,
description?:string,
defaultTemplate?:string|null
) → { board: TaskBoardSummary }
browser
browser.close
Close this conversation's shared browser when the job is done and nobody is watching.
// mutate
browser.close() → BrowserStatus
browser.open
Open this conversation's shared browser, or return the one already open (created: false).
// mutate
browser.open(fresh?:boolean=false) → BrowserOpenResult
browser.status
Where this conversation's shared browser stands: available in the workspace, attached to your browser server this turn, and the live session if there is one.
// query
browser.status() → BrowserStatus
context
context.around
Orient around a thing you've found — it PLUS its immediate connected context (the docs where the thinking lives, the threads it spawned, who's involved).
// query
context.around(
ref:string,
kind?:GraphNodeKind,
maxBytes?:number=16 KiB
) → ContextAroundResult
context.conversationsSince
The CONVERSATIONS that moved in a time range (the moved list), plus the files each touched and who took part — each moved conversation's own participants, exactly as on around.
// query
context.conversationsSince(
from:string,
until?:string,
roomId|roomSlug?:string,
involving?:string,
limit?:number=20,
maxBytes?:number=16 KiB,
cursor?:string
) → ContextSinceResult{moved,more,…}
context.fileChanges
Recent FILE/FOLDER change events (the compact projection), newest-first — who touched what.
// query
context.fileChanges(
from?:string,
until?:string,
under?:string,
types?:string[],
actor?:string,
limit?:number=25,
maxBytes?:number=16 KiB,
cursor?:string,
order?:'asc'|'desc'=desc
) → {changes,more}
context.references
The BATCHED edge primitive: "what is each of these objects connected to, and when did each reference form?" One hop of graph neighbours of things you already know — the context-cluster sibling of around (which carries the shaped seed).
// query
context.references(
ref:string,
limit?:number=20,
order?:'asc'|'desc'=desc,
edges?:string[],
to?:string[],
direction?:'out'|'in'|'any'=any,
since?:string,
preview?:number=0,
maxBytes?:number=16 KiB,
cursor?:string
) → ReferencesResult{references,more,…}
context.referencesMany
The batch form of references: up to 25 refs (paths and conversation ids mixable) → { results, unresolved, truncated }, one result per ref with truncated saying its per-source limit filled.
// query
context.referencesMany(
refs:string[],
limit?:number=20,
order?:'asc'|'desc'=desc,
edges?:string[],
to?:string[],
direction?:'out'|'in'|'any'=any,
since?:string,
preview?:number=0
) → ReferencesBatchResult{results,unresolved,…}
conversations
conversations.create
Open a conversation in the required room (roomId or roomSlug), which must be a WORKROOM.
// mutate
conversations.create(
body:string,
roomId|roomSlug:string,
modifiedEntries?:{ kind: 'file'|'folder'; id: string }[],
title?:string[≤72],
idempotencyKey?:string,
agents?:ConversationSeatInput[]
) → { conversation: Conversation; message: PostedMessageRow; replayed?: true; unappliedSeats?: Array<{ agentId: string; reason: 'agent_unavailable' | 'execution_config_stale' | 'execution_locked' }> } & AddressedReport
conversations.delete
The one HARD delete — drops the conversation row and every message in the thread (cascade).
// mutate
conversations.delete(
id:string
) → ConversationDeleteManifest{cancelFailures,…}
conversations.follow
Make people FOLLOW a conversation — quietly.
// mutate
conversations.follow(
id:string,
followers:string|string[]
) → ConversationParticipants{roomId,followers,agents,…}
conversations.list
The one list verb, and it FILTERS NOTHING by default: a bare page is every conversation in the workspace — scheduled runs included, one flat page ordered by activity.
// query
conversations.list(
roomId|roomSlug?:string,
contains?:string,
participant?:string,
involving?:string,
ids?:string[],
updatedAfter?:string,
updatedBefore?:string,
createdAfter?:string,
createdBefore?:string,
relevantTo?:string,
scheduled?:boolean,
scheduleId?:string,
taskId|taskReference?:string,
working?:boolean,
queued?:boolean,
finished?:boolean,
sort?:'activity'|'created'=activity,
total?:boolean=false,
summary?:boolean=true,
cursor?:string,
limit?:number=25,
maxBytes?:number=16 KiB,
order?:'asc'|'desc'=desc
) → {conversations,more,…}
conversations.listMessages
A page of the conversation as a person reads it.
// query
conversations.listMessages(
id:string,
include?:'narrative'|'all'=narrative,
turnId?:string,
author?:string,
mentions?:string,
landedAfter?:string,
landedBefore?:string,
limit?:number=20,
order?:'asc'|'desc'=desc,
maxBytes?:number=16 KiB,
cursor?:string,
afterId?:string[excludes cursor,order=desc],
ids?:string[][excludes limit,cursor,order,afterId,include,turnId,author,mentions,landedAfter,landedBefore],
edges?:boolean=false
) → {messages,more}
conversations.participants
Who follows THIS thread, and which agents have worked in it.
// query
conversations.participants(
id:string
) → ConversationParticipants{roomId,followers,agents,…}
conversations.post
Post into an existing conversation.
// mutate
conversations.post(
id:string,
body:string,
modifiedEntries?:{ kind: 'file'|'folder'; id: string }[],
idempotencyKey?:string
) → { message: PostedMessageRow; replayed?: true } & AddressedReport
conversations.read
One conversation's row.
// query
conversations.read(id:string) → { conversation: Conversation }
conversations.readMessage
One message, whole — the read a row's more points at, and the only place an ask is expanded in full: every headline, every answer, the addendum, through whichever message you name (the one that poses the ask or the one that resolves …
// query
conversations.readMessage(
id:string,
startLine?:number=1,
endLine?:number,
maxBytes?:number=16 KiB,
startOffset?:number,
ifSha?:string,
part?:'body'|'addendum'|`answer:${string}`=body
) → MessageRead{id,authorUserId,agentId,turnId,more,…}
conversations.unfollow
The paired verb.
// mutate
conversations.unfollow(
id:string,
followers:string|string[]
) → ConversationParticipants{roomId,followers,agents,…}
conversations.update
Retitle a conversation, or write its summary.
// mutate
conversations.update(
id:string,
title?:string|null[≤72],
summary?:string|null[≤2400],
ifSummaryVersion?:number
) → { conversation: Conversation }
devices
devices.list
Every device brought to this workspace, the same list for every member and agent here: its owner, availability and state, each harness's state, companion version, lastSeenAt, placement, and which of this workspace's agents run on…
// query
devices.list(cursor?:string, maxBytes?:number=16 KiB) → {devices,more}
devices.read
One device brought to this workspace, by its id (from devices.list, or an agent's executor.deviceId on agents.read), with the agents assigned to it, ordered by id.
// query
devices.read(
id:string,
cursor?:string,
maxBytes?:number=16 KiB
) → {more,…}
docs
docs.list
Cabane's user guides, in reading order: slug, title, summary, last-updated day and public URL.
// query
docs.list(cursor?:string, maxBytes?:number=16 KiB) → {guides,more}
docs.read
One user guide as Markdown, the same text as its public page.
// query
docs.read(
slug:string,
startLine?:number=1,
endLine?:number,
maxBytes?:number=16 KiB,
startOffset?:number,
ifSha?:string
) → DocsGuideContent{more,…}
files
files.archive
Take something out of the way WITHOUT moving it — the row is stamped archived at the path it already had, so every link into it still opens.
// mutate
files.archive(path:string) → StateManifest{path,entries,…}
files.copy
Copy without streaming bytes.
// mutate
files.copy(
from:string,
to:string,
recursive?:boolean=false,
onConflict?:'error'|'rename'=error
) → FileCopyResult{sha256,…}
files.delete
Soft-delete.
// mutate
files.delete(
path:string,
recursive?:boolean=false
) → DeleteManifest{path,entries,…}
files.edit
Modify a text file in place, atomically.
// mutate
files.edit(
path:string,
edits:FileEditInput|FileEditInput[],
ifSha?:string
) → FileEditResult{path,sha256,…}
files.import
The BYTE path (write is text-only): the SERVER fetches an https url into the workspace at path — no bytes ride through model context.
// mutate
files.import(
url:string,
path:string,
overwrite?:boolean=false,
mkdirs?:boolean=true,
mime?:string
) → FileWriteResult{path,sha256,…}
files.list
List a folder (omit path for the root /).
// query
files.list(
path?:string,
mime?:string,
contains?:string,
updatedAfter?:string,
updatedBefore?:string,
recursive?:boolean=false,
maxBytes?:number=16 KiB
) → FolderListing{path,folders,files,…}
files.listArchive
What is ARCHIVED — out of the way at the path it always had, not moved anywhere.
// query
files.listArchive(
from?:string,
until?:string,
under?:string,
rootsOnly?:boolean=false,
limit?:number=50,
maxBytes?:number=16 KiB,
cursor?:string,
order?:'asc'|'desc'=desc
) → {entries,more}
files.listTrash
The soft-deleted entries (files + folders), most recently deleted first — pass one's path to restore.
// query
files.listTrash(
from?:string,
until?:string,
under?:string,
rootsOnly?:boolean=false,
limit?:number=50,
maxBytes?:number=16 KiB,
cursor?:string,
order?:'asc'|'desc'=desc
) → {entries,more}
files.listVersions
The file's append-only version history, newest-first (order: 'asc' for v1-up), paginated.
// query
files.listVersions(
path:string,
limit?:number=50,
maxBytes?:number=16 KiB,
cursor?:string,
order?:'asc'|'desc'=desc
) → FileVersionsResult{path,fileId,versions,more,…}
files.mkdir
Create a folder.
// mutate
files.mkdir(path:string, recursive?:boolean=false) → {path,…}
files.move
Move or rename.
// mutate
files.move(
from:string,
to:string
) → { from: string; to: string; kind: 'file' | 'folder'; invalidated: MoveInvalidation }
files.read
Read one file.
// query
files.read(
path:string,
startLine?:number=1,
endLine?:number,
maxBytes?:number=16 KiB,
startOffset?:number,
ifSha?:string
) → FileRead{path,sha256,more,…}
files.readMany
MANY files under a glob, in one call, projected to what you need — { entries, more }, always a collection.
// query
files.readMany(
pattern:string,
include?:'properties'|'content'|'both'=properties,
includeArchived?:boolean=false,
maxBytes?:number=16 KiB,
cursor?:string
) → ReadManyResult{entries,more,…}
files.readVersion
The bytes of one older version (versionId from a listVersions row).
// query
files.readVersion(
path:string,
versionId:string,
startLine?:number=1,
endLine?:number,
maxBytes?:number=16 KiB,
startOffset?:number,
ifSha?:string
) → VersionContentResult{path,versionId,more,…}
files.restore
Lift the tombstone on a soft-deleted entry, addressed by the path it had when deleted (match a listTrash() entry).
// mutate
files.restore(path:string) → RestoreManifest{path,entries,…}
files.restoreVersion
Restore an earlier version's bytes onto the file — the recovery half of the history surface.
// mutate
files.restoreVersion(
path:string,
versionId:string
) → RestoreVersionResult{path,sha256,…}
files.setProperties
Set a document's properties (its leading --- block) as data instead of find-and-replacing text.
// mutate
files.setProperties(
path:string,
properties:Record<string,unknown>,
ifSha?:string
) → FileEditResult{path,sha256,…}
files.stat
A cheap existence/metadata probe that NEVER throws on a missing path — it returns { exists: false }.
// query
files.stat(path:string) → FileStat{sha256,…}
files.unarchive
Bring an archived entry back to the live tree, addressed by its path.
// mutate
files.unarchive(path:string) → StateManifest{path,entries,…}
files.write
Create a file.
// mutate
files.write(
path:string,
content:string,
overwrite?:boolean=false,
mkdirs?:boolean=true,
mime?:string,
ifSha?:string[requires overwrite=true],
properties?:'keep'|object[excludes dangerouslyClearProperties],
dangerouslyClearProperties?:boolean=false
) → FileWriteResult{path,sha256,…}
find
find.paths
Names/paths by glob (anchored at root; ** crosses segments) — reads no bodies, cheap.
// query
find.paths(
pattern:string,
maxBytes?:number=16 KiB,
cursor?:string,
includeArchived?:boolean=false
) → PathsResult{paths,more,…}
find.scan
Every matching LINE under a subtree — a bounded WORKSPACE SCAN that reads file bodies (the EXPENSIVE discovery verb).
// query
find.scan(
pattern:string,
under?:string,
includeArchived?:boolean=false,
ignoreCase?:boolean=false,
fixed?:boolean=false,
maxBytes?:number=16 KiB,
cursor?:string
) → ScanResult{matches,more,…}
find.search
Ranked, indexed, CHEAP discovery across file names/content AND conversation titles/messages — the default first move when you don't know where a thing lives.
// query
find.search(
q:string,
tiers?:Array<'named'|'distilled'|'raw'>,
from?:{ conversationId?: string; roomId?: string; roomSlug?: string },
explain?:boolean=false,
matchOn?:'name'|'content'|'all'=all,
types?:Array<'files'|'conversations'|'tasks'>,
conversationId?:string[excludes roomId,roomSlug,under],
author?:string,
mentions?:string,
landedAfter?:string,
landedBefore?:string,
conversationMode?:'grouped'|'messages'=grouped,
roomId|roomSlug?:string,
under?:string,
limit?:number=30,
maxBytes?:number=16 KiB,
cursor?:string,
includeArchived?:boolean=false
) → SearchResult{tiers,results,more,…}
people
people.list
The workspace's people (owner first), each { id, membershipId, name, handle, avatarUrl, email, role }.
// query
people.list(cursor?:string, maxBytes?:number=16 KiB) → {members,more}
rooms
rooms.archive
Soft-archive a room — which CLOSES it (CT1639).
// mutate
rooms.archive(id|slug:string) → { room: RoomRow }
rooms.create
Create a PUBLIC room and its /rooms/{slug} reserved folder (with its ABOUT.md charter).
// mutate
rooms.create(
name:string[≤80],
type?:'chatroom'|'workroom'=workroom,
charter?:string,
people?:string|string[],
defaultAgent?:string|null,
visibility?:'public'=public
) → { room: RoomRow }
rooms.join
Put people in the room — quietly.
// mutate
rooms.join(
id|slug:string,
people:string|string[]
) → RoomReadResult{people,agents,pins,…}
rooms.leave
Take people out of the room — the paired verb.
// mutate
rooms.leave(
id|slug:string,
people:string|string[]
) → RoomReadResult{people,agents,pins,…}
rooms.list
The workspace's rooms.
// query
rooms.list(
cursor?:string,
maxBytes?:number=16 KiB,
includeArchived?:boolean=false,
member?:string,
type?:'chatroom'|'workroom'
) → {rooms,more}
rooms.pin
Pin one of the room's OWN files to it — the shortlist under the room header's Files chevron, where everyone in the room sees it.
// mutate
rooms.pin(
id|slug:string,
path:string
) → RoomReadResult{people,agents,pins,…}
rooms.read
One room whole: its row, the path of its charter (ABOUT.md), the people who joined it and the agents in it.
// query
rooms.read(id|slug:string) → RoomReadResult{people,agents,pins,…}
rooms.repairFolder
Repair legacy record/folder desync by moving the named reserved room folder to the record's canonical homeFolder.
// mutate
rooms.repairFolder(
id|slug:string,
fromPath:string,
replaceGeneratedHome?:boolean=false
) → RoomFolderRepairReceipt
rooms.unarchive
Restore a soft-archived room to the sidebar, its reserved folder with it — and reopen it: posting, opening conversations and waking work again (CT1639).
// mutate
rooms.unarchive(id|slug:string) → { room: RoomRow }
rooms.unpin
Unpin a file from the room.
// mutate
rooms.unpin(
id|slug:string,
path:string
) → RoomReadResult{people,agents,pins,…}
rooms.update
The one configure verb — change a room's name, description or seated agent in one partial write.
// mutate
rooms.update(
id|slug:string,
name?:string[≤80],
description?:string|null[≤1000],
defaultAgent?:string|null,
owner?:string
) → { room: RoomRow }
schedules
schedules.cancel
Cancel a recurring schedule — a terminal stop (use pause for a reversible hold).
// mutate
schedules.cancel(id:string) → { schedule: ScheduleRow }
schedules.create
Create a recurring schedule that dispatches agent on the cron cadence, into exactly one target: targetRoomId, where each fire opens a new conversation, or targetConversationId, where each fire posts a message into that existing conve…
// mutate
schedules.create(
agent:string,
title:string,
prompt:string[≤16KiB],
targetRoomId|targetRoomSlug|targetConversationId:string,
cron:string,
tz:string,
principal?:'creator'|'workspace'=creator
) → { schedule: ScheduleRow }
schedules.list
The workspace's live RECURRING schedules (active/paused), soonest-created first.
// query
schedules.list(
agent?:string,
state?:ScheduleState|ScheduleState[],
targetRoomId|targetRoomSlug?:string,
targetConversationId?:string,
limit?:number=25,
maxBytes?:number=16 KiB,
cursor?:string,
order?:'asc'|'desc'=desc
) → {schedules,more}
schedules.pause
Pause a recurring schedule — stops firing until resumed (missed fires are skipped, never backfilled).
// mutate
schedules.pause(id:string) → { schedule: ScheduleRow }
schedules.read
One schedule whole — either kind, any state — including the standing prompt a list row only excerpts.
// query
schedules.read(id:string) → { schedule: ScheduleView }
schedules.resume
Resume a paused recurring schedule — its next run is recomputed from now.
// mutate
schedules.resume(id:string) → { schedule: ScheduleRow }
schedules.runNow
Fire a schedule ONCE, right now — the way to find out whether a schedule works without waiting for its cadence.
// mutate
schedules.runNow(
id:string
) → { schedule: ScheduleRow } & ConversationLabels
schedules.update
Patch a recurring schedule — any of title / prompt / recurrence (pass BOTH cron and tz) / targetRoomId or targetConversationId / agent / principal.
// mutate
schedules.update(
id:string,
title?:string,
prompt?:string[≤16KiB],
cron?:string[requires tz],
tz?:string[requires cron],
targetRoomId|targetRoomSlug|targetConversationId?:string,
agent?:string,
principal?:'creator'|'workspace'
) → { schedule: ScheduleRow }
skills
skills.list
Every skill reachable this turn, Cabane-origin first, then the turn's room's, then the workspace's.
// query
skills.list(cursor?:string, maxBytes?:number=16 KiB) → {skills,more}
skills.read
One skill by name — the file as authored, frontmatter included.
// query
skills.read(
name:string,
startLine?:number=1,
endLine?:number,
maxBytes?:number=16 KiB,
startOffset?:number,
ifSha?:string
) → SkillContent{path,roomId,more,…}
tags
tags.create
Create a trimmed, case-insensitive unique tag.
// mutate
tags.create(name:string) → { tag: TaskTag }
tags.delete
Remove an unused tag.
// mutate
tags.delete(
id:string,
ifVersion:number
) → { deleted: true; tag: TaskTag }
tags.list
Workspace-wide tags, paged.
// query
tags.list(
limit?:number=100,
cursor?:string,
maxBytes?:number=16 KiB
) → {tags,more}
tags.update
Rename a tag everywhere without changing its identity.
// mutate
tags.update(id:string, name:string, ifVersion:number) → { tag: TaskTag }
tasks
tasks.bind
Bind the task to an existing conversation in its board's room — your own conversation included.
// mutate
tasks.bind(
id|reference:string,
ifVersion:number,
conversationId:string
) → TaskWriteResult{told,…}
tasks.close
Close the task now as done or dropped, whatever steps remain, with an optional reason.
// mutate
tasks.close(
id|reference:string,
ifVersion:number,
kind:'done'|'dropped',
reason?:string
) → TaskWriteResult{told,…}
tasks.complete
Mark the current step done, with optional output.
// mutate
tasks.complete(
id|reference:string,
ifVersion:number,
stepId|stepName:string,
output?:string
) → TaskWriteResult{told,…}
tasks.create
Create a task and its description together, unstarted: nobody is told and no conversation opens until tasks.start.
// mutate
tasks.create(
title:string[≤60],
boardId|boardSlug|boardPrefix:string,
idempotencyKey:string,
intent?:string[≤2000],
supervisor?:string,
template?:string,
slots?:Record<string,string>,
steps?:StepInput[],
tagIds?:string[],
tagNames?:string[],
body?:string,
conversationId?:string
) → TaskWriteResult{told,…}
tasks.delete
Delete the task outright.
// mutate
tasks.delete(id|reference:string, ifVersion:number) → {told,…}
tasks.hand
Hand a step to another agent (to: null returns it to the supervisor).
// mutate
tasks.hand(
id|reference:string,
ifVersion:number,
stepId|stepName:string,
to:string|null
) → TaskWriteResult{told,…}
tasks.list
Workspace tasks, filtered before pagination.
// query
tasks.list(
limit?:number=50,
cursor?:string,
maxBytes?:number=16 KiB,
createdAfter?:string,
createdBefore?:string,
updatedAfter?:string,
updatedBefore?:string,
involving?:string,
boardId|boardSlug|boardPrefix?:string,
state?:TaskState|TaskState[],
tagIds?:string[],
tagNames?:string[],
untagged?:boolean,
roomIds?:string[],
roomSlugs?:string[],
contains?:string,
owner?:string,
supervisor?:string,
ready?:boolean,
includeArchived?:boolean=false,
started?:boolean,
order?:'asc'|'desc'=desc
) → TaskListResult{tasks,counts,more,…}
tasks.openConversation
Open the task's conversation now, without waiting for a row to open one — the same conversation the system would open, in the board's room, bound to the task, so later rows land in it.
// mutate
tasks.openConversation(id|reference:string) → TaskWriteResult{told,…}
tasks.plan
Edit the plan: add steps (after a named step, or first), remove to-do steps, move steps, and name the plan's release step (releases).
// mutate
tasks.plan(
id|reference:string,
ifVersion:number,
add?:(StepInput & { afterId?: string|null; afterName?: string|null })[],
removeIds?:string[],
removeNames?:string[],
move?:{ stepId?: string; stepName?: string; afterId?: string|null; afterName?: string|null }[],
releasesId|releasesName?:string|null
) → TaskWriteResult{told,…}
tasks.read
One task by id or reference (CT945), whichever you hold, with its full plan — an object, never JSON text.
// query
tasks.read(
id|reference:string,
maxBytes?:number=16 KiB,
part?:string,
startLine?:number,
startOffset?:number,
ifVersion?:number,
ifSha?:string,
fromStep?:number
) → TaskReadResult{more,…}
tasks.reopen
Put a done or skipped step back to to-do; every step after it goes back too, and a closed task reopens.
// mutate
tasks.reopen(
id|reference:string,
ifVersion:number,
stepId|stepName:string
) → TaskWriteResult{told,…}
tasks.skip
Skip a step with a reason.
// mutate
tasks.skip(
id|reference:string,
ifVersion:number,
stepId|stepName:string,
reason:string
) → TaskWriteResult{told,…}
tasks.start
Start the task: its first step becomes current, its row lands in the task's conversation (opened if none is bound) and its owner is told, with your note on the row — you included, when the first step is yours: you're woken there, and `to…
// mutate
tasks.start(
id|reference:string,
ifVersion:number,
note?:string
) → TaskWriteResult{told,…}
tasks.update
Update title, intent, supervisor or tags with ifVersion from the last read, or set autostart.
// mutate
tasks.update(
id|reference:string,
ifVersion:number,
title?:string[≤60],
intent?:string[≤2000],
supervisor?:string,
tagIds?:string[],
tagNames?:string[],
autostart?:boolean
) → TaskWriteResult{told,…}
turns
turns.interrupt
Force a running agent to read a message that is waiting behind their turn, NOW, by stopping that turn.
// mutate
turns.interrupt(messageId:string, agent:string) → InterruptResult
turns.list
List completed turns in this workspace, newest first by default.
// query
turns.list(
from?:string,
until?:string,
roomId|roomSlug?:string,
requestedBy?:string,
conversationId?:string,
agent?:string,
runtime?:string,
model?:string,
outcome?:TurnOutcome|TurnOutcome[],
resultReason?:TurnResultReason['kind'],
limit?:number=50,
maxBytes?:number=16 KiB,
cursor?:string,
order?:'asc'|'desc'=desc
) → {turns,more}
turns.listActivity
A page of one turn's thinking and tool rows — what a turn actually did, step by step.
// query
turns.listActivity(
id:string,
phase?:'start'|'done'|'error',
limit?:number=50,
maxBytes?:number=16 KiB,
cursor?:string,
order?:'asc'|'desc'=asc
) → {rows,more}
turns.readActivity
One activity row's scalar, sliced — a tool call's input, result or label, or a thinking block's text.
// query
turns.readActivity(
id:string,
startLine?:number=1,
endLine?:number,
maxBytes?:number=16 KiB,
startOffset?:number,
ifSha?:string,
part?:'summary'|'label'|'input'|'result'|'text'
) → ActivityRead{id,turnId,more,…}
turns.running
Who is executing RIGHT NOW — every running turn in the workspace, with its conversation and latest visible line.
// query
turns.running(
roomId|roomSlug?:string,
conversationId?:string,
agent?:string,
limit?:number=50,
maxBytes?:number=16 KiB,
cursor?:string,
order?:'asc'|'desc'=desc
) → {turns,more}
workspace
workspace.clearAvatar
Clear the workspace's avatar back to the letter mark.
// mutate
workspace.clearAvatar() → { workspace: WorkspaceDetail }
workspace.read
The workspace you are acting in — its name, slug, short id, default agent, avatar and who may edit its charter.
// query
workspace.read() → { workspace: WorkspaceDetail }
workspace.setAvatar
Set the workspace's avatar.
// mutate
workspace.setAvatar(ref:AvatarRef) → { workspace: WorkspaceDetail }