Requests
Every request of the Agents API v1 and its response, with exact JSON, the rights each one needs and the refusals it can get.
Every example on this page is the request field of an envelope; the line under it is the response. Fields marked optional may be left out. Terminal ids, session ids and run ids are numbers; names are strings.
| Group | Requests |
|---|---|
| Agents | List, ListAll, SubscribeAgents |
| Messages and screens | Wait, Read, Check, Send |
| Workers | Spawn, Close |
| Sessions, worktrees, files and changes | Sessions, CreateSession, CloseSession, CreateWorktree, OpenFile, Changes |
| Kraddies and automations | Kraddies, RunKraddie, Automations, RunAutomation, SwitchAutomation, RememberKraddie, KraddieMemory, NewKraddieChat |
| Memory | KraddieRecall, ShareKraddieMemory, MemorySearch, MemoryRead |
| Variants | RunVariants, Variants, PickVariant |
| Handshake | Hello |
Agents
List
The agents of the caller's environment: terminals and chats, not file or extension tabs. For a "Client", the agents of every open environment.
"List"
{"Agents":[{"environment":"main","terminal":4,"title":"Claude Code · 4","group":"api","state":"working","harness":"Claude Code","is_self":false}]}| Field | Meaning |
|---|---|
environment | The environment's name. Omitted in some answers to a terminal, which only sees its own environment. |
terminal | The terminal id, unique within the environment |
title | The tab's title |
group | The group's name, or null |
state | idle, working, waiting-for-input, done, exited or closed. See Agent states. |
harness | Shell, Claude Code, Codex, opencode, Gateway, or acp:<id> for an ACP agent; null when unknown |
is_self | true on the caller's own terminal |
ListAll
List plus the Workers that were closed, with state closed.
"ListAll"SubscribeAgents
A stream of agent events that keeps the connection open. See Subscriptions.
{"SubscribeAgents":{"filter":{"group":"api"}}}Messages and screens
Wait
Blocks until a terminal stops working and answers its settled state, or "TimedOut". timeout_secs is capped at 1800. A terminal the app is still starting counts as working.
{"Wait":{"target":4,"timeout_secs":600}}
{"Settled":{"target":4,"state":"done"}}Read
The last lines lines of a terminal's screen, or of a chat's conversation.
{"Read":{"target":4,"lines":40}}
{"Screen":"..."}A lead that reads one of its Workers after the Worker has finished closes it, as Close would. Reading a closed Worker answers not_found ("send it a message to reopen it").
Check
The caller's unread mailbox messages. With wait_secs, optional, it blocks until one arrives, capped at 1800 seconds. A lead's chat has no mailbox and gets unsupported.
{"Check":{"wait_secs":600}}
{"Messages":[{"id":3,"from":4,"from_title":"Claude Code · 4","body":"API done"}]}Send
Lead only. Types body into a Worker as its next message, as the user would. A closed Worker reopens with its conversation first.
{"Send":{"to":12,"body":"Add a test for the empty case"}}
{"Submitted":{"terminal":12}}Workers
Spawn
Lead only. Starts a Worker in a session of its own in the lead's group, as a chat, and answers once it has started. agent is a harness program (claude, codex, opencode) or acp:<id>; worktree, optional, names a new git worktree to run it in.
{"Spawn":{"agent":"codex","worktree":"fix-login","task":"Fix the login redirect. Done when ..."}}
{"Spawned":{"terminal":12}}Close
Lead only. Closes Workers or a session.
{"Close":{"target":{"agent":12},"when_working":"refuse","worktree":"keep"}}
{"Closed":[{"target":{"agent":12},"worktree":{"path":"/src/app.worktrees/fix-login","outcome":"kept"}}]}| Field | Values |
|---|---|
target | {"agent":N}, {"session":N} or "all_idle", every Worker of the lead that has finished |
when_working | Optional. "refuse", the default: a Worker still working or waiting for input is refused with busy. "cancel_turn": its turn is stopped first. |
worktree | Optional. "keep", the default, or "remove": removes the Worker's worktree only when it has no uncommitted changes, no commits missing from the repository's checked-out branch, and no other session uses it. |
Each entry of Closed names what closed and, when it had one, where its worktree is and what happened to it: "kept", "removed", or {"refused":{"code":"worktree_not_clean","message":"..."}}. An empty list means there was nothing to close. The closed Worker's chat is kept, and a later Send reopens it.
| Refusal | Code |
|---|---|
| No Worker or session with that id | not_found |
| The Worker is already closed | not_found |
| Not one of the lead's Workers, or a session outside its group | not_owned |
| The lead's own session | forbidden |
Still working, without cancel_turn | busy |
| A session of an environment that is not the one on screen | unsupported |
| The caller is not a lead | forbidden |
Sessions, worktrees, files and changes
These act in the caller's environment and group.
Sessions
"Sessions"
{"Sessions":[{"session":2,"name":"API","group":"api","is_current":true,"terminals":[4,7]}]}CreateSession
Opens a session in the caller's group, or in the group named group, without taking the user's place on screen. Both fields are optional.
{"CreateSession":{"name":"Docs","group":null}}
{"SessionCreated":{"session":5}}CloseSession
Lead only. Closes a session of the lead's group and the Workers it holds. The last session of a group that still has tabs cannot be closed (failed).
{"CloseSession":{"session":5}}
{"SessionClosed":{"session":5}}CreateWorktree
A git worktree of the group's repository on a new branch, opened as a group of its own.
{"CreateWorktree":{"name":"fix-login"}}
{"WorktreeCreated":{"group":"fix-login","path":"/src/app.worktrees/fix-login","branch":"fix-login"}}OpenFile
Opens a file of the caller's group in the app's editor. path is relative to the group's folder; position is optional, 1-based, with an optional column. Paths that climb out of the folder, directly or through a link, are refused with forbidden.
{"OpenFile":{"path":"src/main.rs","position":{"line":12,"column":5}}}
{"Opened":{"path":"/src/app/src/main.rs"}}Changes
The git changes of a session's group, the caller's when session is null, with the patch against HEAD.
{"Changes":{"session":null}}
{"Changes":{"group":"api","root":"/src/app","branch":"main","files":[{"path":"src/lib.rs","kind":"modified"}],"patch":"diff --git ..."}}kind is modified, added, deleted, renamed, untracked or conflicted.
Kraddies and automations
Kraddies and their automations belong to the user, not to an environment, so these requests answer the same from every terminal. name matches a Kraddie's name or id.
| Request | Response |
|---|---|
"Kraddies" | {"Kraddies":[{"id":"owl","name":"Owl","switch":"on","harness":"Claude Code","schedule":"...","next_run":"...","last_outcome":"..."}]}; schedule, next_run and last_outcome are left out when they do not apply |
{"RunKraddie":{"name":"owl","prompt":null}} | {"KraddieStarted":{"kraddie":"owl","run":4}}: the Kraddie wakes and runs its manual automation, or its first one |
"Automations" | {"Automations":[{"kraddie":"owl","id":1,"name":"Docs","switch":"on","triggers":["..."],"next_run":"...","last_outcome":"...","runs":3}]} |
{"RunAutomation":{"name":"owl/Docs","prompt":"Only the API folder"}} | {"AutomationStarted":{"kraddie":"owl","automation":"Docs","run":7}} |
{"SwitchAutomation":{"name":"Docs","switch":"off"}} | {"AutomationSwitched":{...}}, with the automation as Automations lists it |
{"RememberKraddie":{"name":"owl","text":"CI uses runner 7"}} | {"KraddieMemory":{"kraddie":"owl","lines":["CI uses runner 7"],"limit":200}}: hands the Kraddie a keepsake |
{"KraddieMemory":{"name":"owl"}} | The same answer: the keepsakes it carries and how many it may keep |
{"NewKraddieChat":{"name":"owl"}} | {"KraddieChatOpened":{"kraddie":"owl","session":9,"terminal":31}}: a new chat that belongs to the Kraddie |
- Write
<kraddie>/<name>for an automation when two Kraddies have an automation of that name; otherwise the answer isbad_request. promptis optional inRunKraddieandRunAutomation.next_run,last_outcome,scheduleandtriggersare display text for people, not values to parse.
Memory
A Kraddie remembers keepsakes, short lines it carries into every run, and chat digests, facts the app draws from its chats. Ordinary chats, those of no Kraddie, have digests of their own. See Kraddie chats and memory.
KraddieRecall
A Kraddie's keepsakes, digests, the Kraddies it reads and whether its digests are automatic. view is "list", the default, which may be left out, or "show"; the CLI prints every fact with show.
{"KraddieRecall":{"name":"owl","view":"show"}}
{"KraddieRecall":{"kraddie":"owl","keepsakes":["CI uses runner 7"],"digests":[{"id":"kraddie/owl/digest/3","chat":"Release notes","facts":["Releases are tagged from main"]}],"reads":["fox"],"automatic_digests":true}}ShareKraddieMemory
Lets reader read the memory of from ("on"), or stops it ("off"). Sharing has a direction: the Kraddie read from does not read its reader back. A Kraddie always reads its own memory, so naming it twice is bad_request.
{"ShareKraddieMemory":{"reader":"owl","from":"fox","switch":"on"}}
{"KraddieShared":{"kraddie":"owl","reads":["fox"]}}MemorySearch and MemoryRead
Search the memory the caller may read, then read one entry in full. limit is optional: 8 by default, between 1 and 30.
{"MemorySearch":{"query":"staging","limit":8}}
{"MemoryHits":[{"id":"chats/digest/1","title":"Staging","excerpt":"Staging deploys from the main branch"}]}{"MemoryRead":{"id":"kraddie/fox/keepsake/2"}}
{"MemoryEntry":{"id":"kraddie/fox/keepsake/2","text":"..."}}| Memory id | Entry |
|---|---|
kraddie/<id>/keepsake/<n> | A keepsake, 1-based |
kraddie/<id>/digest/<n> | A digest of one of the Kraddie's chats |
chats/digest/<n> | A digest of an ordinary chat |
A malformed id is bad_request, an unknown one not_found.
Visibility
What a caller may read is decided on every call:
- Everyone may read the digests of ordinary chats.
- A chat that belongs to a Kraddie reads that Kraddie's memory and the memory of the Kraddies it reads.
- A chat also reads the Kraddies the user mentioned in it with
$. - Anything else is refused:
MemoryReadwithforbidden, andKraddieMemoryandKraddieRecallof a Kraddie out of reach without_of_reach.
Only the user changes memory
RememberKraddie and ShareKraddieMemory sent from a chat are refused with forbidden. They work from the user's own terminal and in the app.
The memory tools
The app's MCP server, krad mcp (server name krad-code), offers chats two read-only tools, memory_search (query, optional limit from 1 to 30) and memory_read (id). They make the two requests above with the same visibility rules, and are listed only while there is a Kraddie or an ordinary chat digest to read.
Variants
A variants run gives one task to two to four variants, each a harness with an optional model and extra instruction, in a worktree of its own, to compare them in the app's Variants view. See Variants.
RunVariants
harness is ClaudeCode, Codex, Opencode or Acp:<id>. test, optional, is a project task such as cargo test, run in each worktree once its variant finishes. group, optional, names the group; the caller's by default.
{"RunVariants":{"prompt":"Fix the flaky upload test","variants":[{"harness":"Codex","model":"gpt-5.5"},{"harness":"ClaudeCode","instruction":"Keep the diff small"}],"test":"cargo test"}}
{"VariantsStarted":{"run":4}}Variants
Every run of the group, or the run named, each with its variants' state, cost, tokens, time, test result and diff.
{"Variants":{"run":4}}The shape of each run in a Variants answer follows the app's own record of it and is not part of the stable surface. Read it for display only.
PickVariant
Lead only. Keeps the winner and discards the other variants and their worktrees. outcome is "keep_worktree", where the winner's worktree becomes its session, or "apply_onto_base", where its changes are applied onto the base worktree. confirmed must be true. A run of another group is not_owned.
{"PickVariant":{"run":4,"variant":1,"outcome":"keep_worktree","confirmed":true}}
{"VariantPicked":{"run":4,"variant":1}}Requests the app's integrations use
Hook, Status, Ask and Askpass carry harness hooks, status lines, permission asks and git credential prompts from the processes the app starts. Code, Tools and ExtensionTool serve the code intelligence, the tool catalog and the extension tools behind krad code, krad tools, krad tool and krad mcp.
Not stable
These requests are part of the protocol so the app's own pieces can use it, but their payloads follow the vendors' formats and may change with them. Programs should not depend on them.