2026-10-13 22:19:20 -07:00
openapi : 3.0.3
info :
title : byre
version : 0.0.0
paths :
/api/me :
get :
operationId : getMe
responses :
"200" :
description : The calling user.
content :
application/json :
schema : { $ref : "#/components/schemas/User" }
put :
operationId : updateMe
requestBody :
required : true
content :
application/json :
schema : { $ref : "#/components/schemas/UserUpdate" }
responses :
"200" :
description : The updated user.
content :
application/json :
schema : { $ref : "#/components/schemas/User" }
"400": { $ref : "#/components/responses/Error" }
2026-10-14 21:25:01 -07:00
/api/me/notifications :
put :
operationId : updateNotificationPrefs
description : Sets which inbox items the calling user is sent push notifications for.
requestBody :
required : true
content :
application/json :
schema : { $ref : "#/components/schemas/NotificationPrefs" }
responses :
"200" :
description : The updated user.
content :
application/json :
schema : { $ref : "#/components/schemas/User" }
"400": { $ref : "#/components/responses/Error" }
/api/me/push-subscriptions :
post :
operationId : addPushSubscription
description : Registers a browser's push subscription for the calling user. Registering an endpoint again replaces it.
requestBody :
required : true
content :
application/json :
schema : { $ref : "#/components/schemas/PushSubscription" }
responses :
"204" :
description : Registered.
"400": { $ref : "#/components/responses/Error" }
delete :
operationId : removePushSubscription
parameters :
- { name : endpoint, in : query, required : true, schema : { type : string } }
responses :
"204" :
description : Removed, or was not registered.
2026-10-15 09:40:30 -07:00
/api/me/lead/sessions :
get :
operationId : listLeadSessions
description : The calling user's lead agent sessions, oldest first. A compaction completes one and starts the next.
responses :
"200" :
description : The sessions.
content :
application/json :
schema :
type : array
items : { $ref : "#/components/schemas/AgentSession" }
/api/me/lead/messages :
post :
operationId : messageLead
description : >
Sends a message to the calling user's lead agent, starting a lead session when there is none.
While the lead is mid-turn the message is held and sent as its next turn.
requestBody :
required : true
content :
application/json :
schema : { $ref : "#/components/schemas/MessageCreate" }
responses :
"202" :
description : The lead session the message went to or is held for.
content :
application/json :
schema : { $ref : "#/components/schemas/AgentSession" }
"400": { $ref : "#/components/responses/Error" }
/api/me/focus :
get :
operationId : getFocus
responses :
"200" :
description : What the calling user's right pane shows.
content :
application/json :
schema : { $ref : "#/components/schemas/Focus" }
put :
operationId : setFocus
2026-10-15 09:59:13 -07:00
description : Records the human switching the right pane's project, task or tab.
2026-10-15 09:40:30 -07:00
requestBody :
required : true
content :
application/json :
schema : { $ref : "#/components/schemas/Focus" }
responses :
"200" :
description : The stored focus.
content :
application/json :
schema : { $ref : "#/components/schemas/Focus" }
"400": { $ref : "#/components/responses/Error" }
"404": { $ref : "#/components/responses/Error" }
2026-10-15 09:59:13 -07:00
/api/me/pane-focus :
put :
operationId : setPaneFocus
description : Records whether the human is working in the right pane. While they are, the lead agent can't move it.
requestBody :
required : true
content :
application/json :
schema : { $ref : "#/components/schemas/PaneFocus" }
responses :
"204" :
description : Recorded.
"400": { $ref : "#/components/responses/Error" }
2026-10-14 21:25:01 -07:00
/api/push/key :
get :
operationId : getPushKey
responses :
"200" :
description : The server's VAPID public key, the applicationServerKey for PushManager.subscribe.
content :
application/json :
schema : { $ref : "#/components/schemas/PushKey" }
2026-10-13 22:19:20 -07:00
/api/projects :
get :
operationId : listProjects
responses :
"200" :
description : All projects.
content :
application/json :
schema :
type : array
items : { $ref : "#/components/schemas/Project" }
post :
operationId : createProject
requestBody :
required : true
content :
application/json :
schema : { $ref : "#/components/schemas/ProjectCreate" }
responses :
"201" :
description : The new project.
content :
application/json :
schema : { $ref : "#/components/schemas/Project" }
"400": { $ref : "#/components/responses/Error" }
/api/projects/{projectId}:
parameters :
- { name : projectId, in : path, required : true, schema : { type : string } }
get :
operationId : getProject
responses :
"200" :
description : The project.
content :
application/json :
schema : { $ref : "#/components/schemas/Project" }
"404": { $ref : "#/components/responses/Error" }
/api/projects/{projectId}/tasks:
parameters :
- { name : projectId, in : path, required : true, schema : { type : string } }
get :
operationId : listTasks
responses :
"200" :
description : The project's tasks, newest first.
content :
application/json :
schema :
type : array
items : { $ref : "#/components/schemas/Task" }
"404": { $ref : "#/components/responses/Error" }
post :
operationId : createTask
description : Creates the task's branch and worktree from the project's default branch.
requestBody :
required : true
content :
application/json :
schema : { $ref : "#/components/schemas/TaskCreate" }
responses :
"201" :
description : The new task.
content :
application/json :
schema : { $ref : "#/components/schemas/Task" }
"400": { $ref : "#/components/responses/Error" }
"404": { $ref : "#/components/responses/Error" }
2026-10-15 07:23:17 -07:00
/api/projects/{projectId}/todo:
parameters :
- { name : projectId, in : path, required : true, schema : { type : string } }
get :
operationId : getTodo
description : The items of TODO.md at the root of the project's default branch, in file order.
responses :
"200" :
description : The items; exists is false when the default branch has no TODO.md.
content :
application/json :
schema : { $ref : "#/components/schemas/Todo" }
"404": { $ref : "#/components/responses/Error" }
/api/projects/{projectId}/todo/tasks:
parameters :
- { name : projectId, in : path, required : true, schema : { type : string } }
post :
operationId : startTodoItem
description : >
Creates a task for a TODO.md item, recording the item as its todo_item, and starts its agent with the item as
the first message. Refused while another active task has the same item.
requestBody :
required : true
content :
application/json :
schema : { $ref : "#/components/schemas/TodoStart" }
responses :
"201" :
description : The new task.
content :
application/json :
schema : { $ref : "#/components/schemas/Task" }
"400": { $ref : "#/components/responses/Error" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
2026-10-13 22:19:20 -07:00
/api/tasks/{taskId}:
parameters :
- { name : taskId, in : path, required : true, schema : { type : string } }
get :
operationId : getTask
responses :
"200" :
description : The task.
content :
application/json :
schema : { $ref : "#/components/schemas/Task" }
"404": { $ref : "#/components/responses/Error" }
2026-10-14 19:35:34 -07:00
/api/tasks/{taskId}/unmerged:
parameters :
- { name : taskId, in : path, required : true, schema : { type : string } }
get :
operationId : getUnmerged
description : What the task's worktree holds that its project's default branch doesn't.
responses :
"200" :
description : The unmerged changes.
content :
application/json :
schema : { $ref : "#/components/schemas/Unmerged" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
2026-10-15 07:15:51 -07:00
/api/tasks/{taskId}/co-authors:
parameters :
- { name : taskId, in : path, required : true, schema : { type : string } }
get :
operationId : getCoAuthors
description : >
The humans other than the caller with a message in the task's transcript (sent its agent a message, or had
an inbox answer delivered under their name), in order of their first message. A merge by the caller gives each one with a git identity a
Co-authored-by trailer.
responses :
"200" :
description : The co-authors.
content :
application/json :
schema :
type : array
items : { $ref : "#/components/schemas/Participant" }
"404": { $ref : "#/components/responses/Error" }
2026-10-14 19:35:34 -07:00
/api/tasks/{taskId}/merge:
2026-10-13 22:19:20 -07:00
parameters :
- { name : taskId, in : path, required : true, schema : { type : string } }
post :
2026-10-14 19:35:34 -07:00
operationId : mergeTask
description : >
2026-10-14 21:01:38 -07:00
Starts the same agent turn as merge-in. When that turn ends normally, byre squashes the task's worktree
2026-10-15 07:15:51 -07:00
into one commit titled with the task's merge_title on the project's default branch, authored by the caller with
a Co-authored-by trailer for each of the task's co-authors, pushes it to origin, fast-forwards the project's
checkout to it, then removes the worktree and branch and marks the task merged. Refused while a turn is running
or queued.
2026-10-13 22:19:20 -07:00
responses :
2026-10-14 21:01:38 -07:00
"202" :
description : The merge turn was started or queued.
2026-10-14 19:35:34 -07:00
content :
application/json :
2026-10-14 21:01:38 -07:00
schema : { $ref : "#/components/schemas/AgentSession" }
"400": { $ref : "#/components/responses/Error" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
/api/tasks/{taskId}/merge-in:
parameters :
- { name : taskId, in : path, required : true, schema : { type : string } }
post :
operationId : mergeIn
description : >
Asks the task's agent to merge the project's default branch into the task branch, resolving any conflicts
and regenerating generated files. Sent to the task's idle session, or starts a session when it has none.
Refused while a turn is running or queued.
responses :
"202" :
description : The merge turn was started or queued.
content :
application/json :
schema : { $ref : "#/components/schemas/AgentSession" }
2026-10-14 19:35:34 -07:00
"400": { $ref : "#/components/responses/Error" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
/api/tasks/{taskId}/discard:
parameters :
- { name : taskId, in : path, required : true, schema : { type : string } }
post :
operationId : discardTask
description : Removes the task's worktree and branch without merging. The task's record and events remain.
responses :
"200" :
description : The discarded task.
2026-10-13 22:19:20 -07:00
content :
application/json :
schema : { $ref : "#/components/schemas/Task" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
2026-10-14 09:40:12 -07:00
/api/tasks/{taskId}/events:
parameters :
- { name : taskId, in : path, required : true, schema : { type : string } }
get :
operationId : listTaskEvents
description : The task's events after a seq, oldest first. Page by passing the last seq back as after.
parameters :
- { name : after, in : query, required : false, schema : { type : integer, format : int64 } }
- { name : limit, in : query, required : false, schema : { type : integer, minimum : 1, maximum : 1000 } }
responses :
"200" :
description : Up to limit events (default 500).
content :
application/json :
schema :
type : array
items : { $ref : "#/components/schemas/Event" }
"404": { $ref : "#/components/responses/Error" }
2026-10-14 19:35:34 -07:00
/api/tasks/{taskId}/changes:
parameters :
- { name : taskId, in : path, required : true, schema : { type : string } }
get :
operationId : getTaskChanges
description : >
Everything in the task's worktree (committed, staged, unstaged and untracked, respecting .gitignore) as a tree,
compared with the merge-base of the task branch and the project's default branch, or with since when given.
2026-10-15 00:08:32 -07:00
The worktree's own index is not touched. With snapshot, the tree is that snapshot's instead, compared with the
merge-base of its commit and the default branch, or with the previous snapshot's tree when step is true.
2026-10-14 19:35:34 -07:00
parameters :
2026-10-15 00:08:32 -07:00
- { name : since, in : query, required : false, schema : { type : string }, description : "A commit to compare with instead of the merge-base, such as a user.message event's head. Not allowed with snapshot." }
- { name : snapshot, in : query, required : false, schema : { type : integer }, description : "A snapshot's n: show the task as it was in that snapshot rather than the live worktree." }
- { name : step, in : query, required : false, schema : { type : boolean }, description : "With snapshot: compare with the previous snapshot (the snapshot commit's parent for the first one)." }
2026-10-14 19:35:34 -07:00
responses :
"200" :
description : Per-file stats.
content :
application/json :
schema : { $ref : "#/components/schemas/TaskChanges" }
"400": { $ref : "#/components/responses/Error" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
2026-10-15 07:27:17 -07:00
/api/tasks/{taskId}/image:
parameters :
- { name : taskId, in : path, required : true, schema : { type : string } }
get :
operationId : getTaskImage
description : >
An image file from the task's worktree, for Markdown images and image attachments. path is absolute or relative
to the worktree; after resolving symlinks it must be inside the worktree. PNG, JPEG, GIF, WebP and SVG, chosen by extension.
parameters :
- { name : path, in : query, required : true, schema : { type : string } }
responses :
"200" :
description : The file's bytes.
content :
image/png : { schema : { type : string, format : binary } }
image/jpeg : { schema : { type : string, format : binary } }
image/gif : { schema : { type : string, format : binary } }
image/webp : { schema : { type : string, format : binary } }
image/svg+xml : { schema : { type : string, format : binary } }
"400": { $ref : "#/components/responses/Error" }
"403": { $ref : "#/components/responses/Error" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
2026-10-14 19:35:34 -07:00
/api/tasks/{taskId}/diff:
parameters :
- { name : taskId, in : path, required : true, schema : { type : string } }
get :
operationId : getTaskDiff
description : The unified diff of one file between a base and tree from getTaskChanges.
parameters :
- { name : base, in : query, required : true, schema : { type : string } }
- { name : tree, in : query, required : true, schema : { type : string } }
- { name : path, in : query, required : true, schema : { type : string } }
- { name : old_path, in : query, required : false, schema : { type : string } }
responses :
"200" :
description : The patch.
content :
application/json :
schema : { $ref : "#/components/schemas/FileDiff" }
"400": { $ref : "#/components/responses/Error" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
2026-10-15 07:31:53 -07:00
/api/tasks/{taskId}/dir:
parameters :
- { name : taskId, in : path, required : true, schema : { type : string } }
get :
operationId : getTaskDir
description : >
One directory of the task's worktree, directories first, then by name. Entries named .git are left out;
gitignored entries are included and marked.
A path that leaves the worktree, through .. or a symlink, is refused.
parameters :
- { name : path, in : query, required : false, schema : { type : string }, description : "Slash-separated, relative to the worktree root; empty or absent for the root." }
responses :
"200" :
description : The directory's entries.
content :
application/json :
schema : { $ref : "#/components/schemas/DirListing" }
"400": { $ref : "#/components/responses/Error" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
/api/tasks/{taskId}/file:
parameters :
- { name : taskId, in : path, required : true, schema : { type : string } }
get :
operationId : getTaskFile
description : >
A regular file in the task's worktree. Text is returned up to a size limit; binary files return no content.
A path that leaves the worktree, through .. or a symlink, is refused.
parameters :
- { name : path, in : query, required : true, schema : { type : string }, description : "Slash-separated, relative to the worktree root." }
responses :
"200" :
description : The file.
content :
application/json :
schema : { $ref : "#/components/schemas/FileContent" }
"400": { $ref : "#/components/responses/Error" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
2026-10-14 22:52:02 -07:00
/api/tasks/{taskId}/snapshots:
parameters :
- { name : taskId, in : path, required : true, schema : { type : string } }
get :
operationId : listSnapshots
description : >
The task's snapshots, oldest first. Each is a commit of the worktree as if everything were staged, kept at
refs/byre/tasks/{taskId}/snap/{n} until the task is merged or discarded; the rows remain after that.
responses :
"200" :
description : The snapshots.
content :
application/json :
schema :
type : array
items : { $ref : "#/components/schemas/Snapshot" }
"404": { $ref : "#/components/responses/Error" }
2026-10-13 22:30:39 -07:00
/api/tasks/{taskId}/sessions:
parameters :
- { name : taskId, in : path, required : true, schema : { type : string } }
get :
operationId : listSessions
responses :
"200" :
description : The task's agent sessions, oldest first.
content :
application/json :
schema :
type : array
items : { $ref : "#/components/schemas/AgentSession" }
"404": { $ref : "#/components/responses/Error" }
post :
operationId : createSession
description : Starts an agent session in the task's worktree and sends it the prompt as its first turn.
requestBody :
required : true
content :
application/json :
schema : { $ref : "#/components/schemas/SessionCreate" }
responses :
"201" :
description : The new session.
content :
application/json :
schema : { $ref : "#/components/schemas/AgentSession" }
"400": { $ref : "#/components/responses/Error" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
/api/sessions/{sessionId}:
parameters :
- { name : sessionId, in : path, required : true, schema : { type : string } }
get :
operationId : getSession
responses :
"200" :
description : The session.
content :
application/json :
schema : { $ref : "#/components/schemas/AgentSession" }
"404": { $ref : "#/components/responses/Error" }
/api/sessions/{sessionId}/messages:
parameters :
- { name : sessionId, in : path, required : true, schema : { type : string } }
post :
operationId : sendMessage
description : Starts a new turn with this message. The session must be idle.
requestBody :
required : true
content :
application/json :
schema : { $ref : "#/components/schemas/MessageCreate" }
responses :
"202" :
description : The turn has started.
content :
application/json :
schema : { $ref : "#/components/schemas/AgentSession" }
"400": { $ref : "#/components/responses/Error" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
2026-10-14 19:35:34 -07:00
/api/sessions/{sessionId}/compact:
parameters :
- { name : sessionId, in : path, required : true, schema : { type : string } }
post :
operationId : compactSession
description : >
Asks the idle session's agent for a handoff (goal, decisions, state, dead ends, open questions, files). When that turn ends,
the session is completed and a new session on the same task and model starts with the handoff as its first message.
responses :
"202" :
description : The handoff turn was started or queued.
content :
application/json :
schema : { $ref : "#/components/schemas/AgentSession" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
2026-10-13 22:30:39 -07:00
/api/sessions/{sessionId}/interrupt:
parameters :
- { name : sessionId, in : path, required : true, schema : { type : string } }
post :
operationId : interruptSession
description : Ends the current turn.
responses :
"202" :
description : The interrupt was delivered.
content :
application/json :
schema : { $ref : "#/components/schemas/AgentSession" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
2026-10-14 20:07:26 -07:00
/api/blobs :
post :
operationId : uploadBlob
description : >
Stores an image for use in a message. The body is the raw image; its type is detected from the bytes
and must be PNG, JPEG, GIF or WebP. At most 5 MiB.
requestBody :
required : true
content :
image/png : { schema : { type : string, format : binary } }
image/jpeg : { schema : { type : string, format : binary } }
image/gif : { schema : { type : string, format : binary } }
image/webp : { schema : { type : string, format : binary } }
responses :
"201" :
description : The stored blob.
content :
application/json :
schema : { $ref : "#/components/schemas/Blob" }
"400": { $ref : "#/components/responses/Error" }
"413": { $ref : "#/components/responses/Error" }
/api/blobs/{blobId}:
parameters :
- { name : blobId, in : path, required : true, schema : { type : string } }
get :
operationId : getBlob
responses :
"200" :
description : The blob's bytes, with its content type.
content :
image/png : { schema : { type : string, format : binary } }
image/jpeg : { schema : { type : string, format : binary } }
image/gif : { schema : { type : string, format : binary } }
image/webp : { schema : { type : string, format : binary } }
"404": { $ref : "#/components/responses/Error" }
2026-10-14 07:02:56 -07:00
/api/inbox :
get :
operationId : listInbox
description : >
Inbox items, highest priority first (blocked, gate, review, fyi), then oldest first.
Filters narrow the one query to a project's or a task's view.
parameters :
- { name : project_id, in : query, required : false, schema : { type : string } }
- { name : task_id, in : query, required : false, schema : { type : string } }
- { name : state, in : query, required : false, schema : { $ref : "#/components/schemas/InboxState" } }
responses :
"200" :
2026-10-14 23:34:39 -07:00
description : Matching items with their responses. Defaults to open items.
2026-10-14 07:02:56 -07:00
content :
application/json :
schema :
type : array
items : { $ref : "#/components/schemas/InboxItem" }
/api/inbox/{itemId}:
parameters :
- { name : itemId, in : path, required : true, schema : { type : string } }
get :
operationId : getInboxItem
responses :
"200" :
description : The item with its responses.
content :
application/json :
schema : { $ref : "#/components/schemas/InboxItem" }
"404": { $ref : "#/components/responses/Error" }
/api/inbox/responses :
post :
operationId : respondInbox
description : >
Answers one or more items in one submission. Answers reach the agent as one message once
it is idle and none of its blocking questions are unanswered.
requestBody :
required : true
content :
application/json :
schema : { $ref : "#/components/schemas/InboxRespond" }
responses :
"200" :
description : The updated items.
content :
application/json :
schema :
type : array
items : { $ref : "#/components/schemas/InboxItem" }
"400": { $ref : "#/components/responses/Error" }
"404": { $ref : "#/components/responses/Error" }
"409": { $ref : "#/components/responses/Error" }
2026-10-13 22:19:20 -07:00
/api/events :
get :
operationId : streamEvents
description : >
Server-sent events. Each event's id is its seq; data is the Event as JSON.
Events after Last-Event-ID (or the after query parameter) are replayed before live events.
2026-10-15 09:40:30 -07:00
With task_id, only that task's events are sent; with lead=true, only the events of the caller's lead agent.
Events with an owner go only to that user.
2026-10-13 22:19:20 -07:00
parameters :
- { name : Last-Event-ID, in : header, required : false, schema : { type : integer, format : int64 } }
- { name : after, in : query, required : false, schema : { type : integer, format : int64 } }
2026-10-14 23:53:17 -07:00
- { name : task_id, in : query, required : false, schema : { type : string } }
2026-10-15 09:40:30 -07:00
- { name : lead, in : query, required : false, schema : { type : boolean } }
2026-10-13 22:19:20 -07:00
responses :
"200" :
description : Event stream.
content :
text/event-stream :
schema : { type : string }
2026-10-14 23:53:17 -07:00
"404": { $ref : "#/components/responses/Error" }
2026-10-13 22:19:20 -07:00
/api/admin/status :
get :
operationId : getStatus
responses :
"200" :
description : Server health and usage.
content :
application/json :
schema : { $ref : "#/components/schemas/Status" }
components :
responses :
Error :
description : Error.
content :
application/json :
schema : { $ref : "#/components/schemas/Error" }
schemas :
Error :
type : object
required : [ message]
properties :
message : { type : string }
User :
type : object
2026-10-14 21:25:01 -07:00
required : [ login, display_name, git_name, git_email, notification_prefs]
2026-10-13 22:19:20 -07:00
properties :
login : { type : string }
display_name : { type : string }
git_name : { type : string }
git_email : { type : string }
2026-10-14 21:25:01 -07:00
notification_prefs : { $ref : "#/components/schemas/NotificationPrefs" }
NotificationPrefs :
type : object
description : Which new inbox items send this user a push notification.
required : [ blocking_questions, questions, reports, errors, rate_limits]
properties :
blocking_questions : { type : boolean, description : "Questions asked with blocking: true. On by default." }
questions : { type : boolean, description : Non-blocking questions. }
reports : { type : boolean, description : Turn summaries. }
errors : { type : boolean, description : session_error items. }
rate_limits : { type : boolean, description : rate_limited items. }
PushSubscription :
type : object
required : [ endpoint, p256dh, auth]
properties :
endpoint : { type : string }
p256dh : { type : string, description : The subscription's p256dh key, base64url. }
auth : { type : string, description : The subscription's auth secret, base64url. }
PushKey :
type : object
required : [ public_key]
properties :
public_key : { type : string, description : Base64url, uncompressed P-256 point. }
2026-10-13 22:19:20 -07:00
UserUpdate :
type : object
required : [ git_name, git_email]
properties :
git_name : { type : string }
git_email : { type : string }
Project :
type : object
required : [ id, name, repo_path, default_branch, remote, created_by, created_at]
properties :
id : { type : string }
name : { type : string }
repo_path : { type : string }
default_branch : { type : string }
remote : { type : string }
created_by : { type : string }
created_at : { type : string, format : date-time }
ProjectCreate :
type : object
required : [ name, repo_path]
properties :
name : { type : string }
repo_path : { type : string }
Task :
type : object
2026-10-14 21:21:54 -07:00
required : [ id, project_id, title, merge_title, branch, worktree_path, base_ref, status, created_by, created_at]
2026-10-13 22:19:20 -07:00
properties :
id : { type : string }
project_id : { type : string }
title : { type : string }
2026-10-14 21:21:54 -07:00
merge_title : { type : string, description : "The title of the squash commit Merge makes: the task title until the agent sets another with set_merge_title." }
2026-10-13 22:19:20 -07:00
branch : { type : string }
worktree_path : { type : string }
base_ref : { type : string }
2026-10-14 19:35:34 -07:00
status :
type : string
enum : [ active, merged, discarded]
x-enum-varnames : [ TaskStatusActive, TaskStatusMerged, TaskStatusDiscarded]
2026-10-13 22:19:20 -07:00
created_by : { type : string }
created_at : { type : string, format : date-time }
2026-10-14 19:35:34 -07:00
closed_at : { type : string, format : date-time, description : When the task was merged or discarded. }
merge_commit : { type : string, description : "merged: the squash commit on the default branch; empty when there was nothing to merge." }
2026-10-15 07:23:17 -07:00
todo_item : { type : string, description : "The title of the TODO.md item the task was started from; absent for other tasks." }
Todo :
type : object
required : [ exists, items]
properties :
exists : { type : boolean, description : Whether the default branch has a TODO.md at its root. }
items :
type : array
items : { $ref : "#/components/schemas/TodoItem" }
TodoItem :
type : object
required : [ title, body, section]
properties :
title : { type : string, description : "The item's first line, without its list marker: the item's identity." }
body : { type : string, description : The item's further lines, as Markdown with the item's indentation removed. }
section : { type : string, description : The text of the nearest heading above the item; empty when there is none. }
TodoStart :
type : object
required : [ title]
properties :
title : { type : string, description : The title of the item to start. }
model : { type : string }
2026-10-14 19:35:34 -07:00
Unmerged :
type : object
required : [ commits, files, insertions, deletions, uncommitted]
properties :
commits : { type : integer, description : Commits on the task branch that aren't on the default branch. }
files : { type : integer, description : Files that differ from the merge base, uncommitted changes included. }
insertions : { type : integer }
deletions : { type : integer }
uncommitted : { type : integer, description : Paths with uncommitted changes in the worktree. }
2026-10-13 22:19:20 -07:00
2026-10-15 07:15:51 -07:00
Participant :
type : object
required : [ login, display_name, git_name, git_email]
properties :
login : { type : string }
display_name : { type : string }
git_name : { type : string, description : Empty when the user hasn't set a git identity; they then get no trailer. }
git_email : { type : string }
2026-10-13 22:19:20 -07:00
TaskCreate :
type : object
required : [ title]
properties :
title : { type : string }
2026-10-14 19:35:34 -07:00
TaskChanges :
type : object
required : [ base, tree, files]
properties :
2026-10-15 00:08:32 -07:00
base : { type : string, description : "The commit or tree compared with: the merge-base of the task branch and the default branch, since, or the previous snapshot's tree." }
tree : { type : string, description : "Tree of the worktree as if everything were staged, or the snapshot's tree." }
2026-10-14 19:35:34 -07:00
files :
type : array
items : { $ref : "#/components/schemas/FileChange" }
FileChange :
type : object
required : [ path, status, additions, deletions, binary]
properties :
path : { type : string }
old_path : { type : string, description : "renamed: the path before the rename." }
status : { type : string, enum : [ added, modified, deleted, renamed, type_changed] }
additions : { type : integer }
deletions : { type : integer }
binary : { type : boolean }
FileDiff :
type : object
required : [ path, patch]
properties :
path : { type : string }
patch : { type : string }
2026-10-15 07:31:53 -07:00
DirListing :
type : object
required : [ path, entries, truncated]
properties :
path : { type : string, description : "The directory, relative to the worktree root; empty for the root." }
entries :
type : array
items : { $ref : "#/components/schemas/DirEntry" }
truncated : { type : boolean, description : The directory has more entries than were returned. }
DirEntry :
type : object
required : [ name, type, symlink, size, ignored]
properties :
name : { type : string }
ignored : { type : boolean, description : "git ignores the entry: .gitignore and the other exclude files match it or a directory above it." }
type :
type : string
enum : [ dir, file, other]
x-enum-varnames : [ DirEntryTypeDir, DirEntryTypeFile, DirEntryTypeOther]
description : "What the entry is, following a symlink that stays in the worktree. other: a symlink that leaves the worktree or points nowhere, or a device, socket or pipe."
symlink : { type : boolean }
size : { type : integer, format : int64, description : "file: its size in bytes." }
FileContent :
type : object
required : [ path, size, binary, truncated, text]
properties :
path : { type : string }
size : { type : integer, format : int64 }
binary : { type : boolean, description : The file isn't UTF-8 text; text is empty. }
truncated : { type : boolean, description : "text holds only the start of the file." }
text : { type : string }
2026-10-14 22:52:02 -07:00
Snapshot :
type : object
required : [ id, task_id, agent_session_id, n, commit_sha, tree_sha, event_seq, trigger, created_at]
properties :
id : { type : string }
task_id : { type : string }
agent_session_id : { type : string }
n : { type : integer, description : "Position in the task's snapshots, from 1; the ref is refs/byre/tasks/{task_id}/snap/{n}." }
commit_sha : { type : string, description : A commit of tree_sha whose parent is the worktree's HEAD when it was taken. }
tree_sha : { type : string }
event_seq : { type : integer, format : int64, description : "The task's latest event when the snapshot was started: the tree holds at least the work up to it." }
trigger :
type : string
enum : [ tool_call, turn_end, ask_human, timer]
x-enum-varnames : [ SnapshotTriggerToolCall, SnapshotTriggerTurnEnd, SnapshotTriggerAskHuman, SnapshotTriggerTimer]
created_at : { type : string, format : date-time }
2026-10-13 22:30:39 -07:00
AgentSession :
type : object
2026-10-15 09:40:30 -07:00
required : [ id, task_id, owner, vendor, model, vendor_session_id, state, role, created_by, created_at]
2026-10-13 22:30:39 -07:00
properties :
id : { type : string }
2026-10-15 09:40:30 -07:00
task_id : { type : string, description : Empty for a lead session. }
owner : { type : string, description : "The login whose lead agent this is; empty for a task's session." }
2026-10-13 22:30:39 -07:00
vendor : { type : string, enum : [ claude] }
model : { type : string, description : Requested model; empty means the vendor's default. }
vendor_session_id : { type : string }
2026-10-14 09:40:12 -07:00
state :
type : string
enum : [ idle, queued, running, completed]
2026-10-14 19:35:34 -07:00
x-enum-varnames : [ AgentSessionStateIdle, AgentSessionStateQueued, AgentSessionStateRunning, AgentSessionStateCompleted]
2026-10-14 09:40:12 -07:00
description : queued means a turn is waiting for a free slot under the concurrency caps.
2026-10-15 09:40:30 -07:00
role : { type : string, enum : [ implementer, lead] }
2026-10-13 22:30:39 -07:00
created_by : { type : string }
created_at : { type : string, format : date-time }
SessionCreate :
type : object
required : [ prompt]
properties :
prompt : { type : string }
model : { type : string }
2026-10-14 20:07:26 -07:00
images :
type : array
items : { type : string }
description : Blob ids from uploadBlob, sent to the agent as images alongside the prompt.
2026-10-13 22:30:39 -07:00
MessageCreate :
type : object
required : [ text]
properties :
2026-10-14 20:07:26 -07:00
text : { type : string, description : May be empty when images are given. }
images :
type : array
items : { type : string }
description : Blob ids from uploadBlob, sent to the agent as images alongside the text.
2026-10-14 19:35:34 -07:00
model :
type : string
description : Model for this turn and later ones. When it differs from the session's model, the session switches before the message is sent.
2026-10-13 22:30:39 -07:00
2026-10-14 20:07:26 -07:00
Blob :
type : object
required : [ id, content_type, created_by, created_at]
properties :
id : { type : string }
content_type : { type : string }
created_by : { type : string }
created_at : { type : string, format : date-time }
2026-10-14 07:02:56 -07:00
Attachment :
type : object
required : [ kind]
properties :
kind : { type : string, enum : [ file, diff, image, diagram, task, snapshot, url] }
2026-10-15 07:27:17 -07:00
path : { type : string, description : "file: repo-relative path. image: an image file in the task's worktree, absolute or relative to it." }
2026-10-14 07:02:56 -07:00
start_line : { type : integer }
end_line : { type : integer }
ref : { type : string, description : "diff: git revision range." }
url : { type : string }
mermaid : { type : string, description : "diagram: Mermaid source." }
image : { type : string, description : "image: data URL." }
task_id : { type : string }
snapshot_id : { type : string }
caption : { type : string }
InboxState :
type : string
2026-10-14 10:37:04 -07:00
enum : [ open, answered, dismissed, superseded]
2026-10-14 07:02:56 -07:00
InboxItem :
type : object
required : [ id, project_id, task_id, agent_session_id, thread_id, kind, priority, blocking, payload, state, created_at, responses]
properties :
id : { type : string }
project_id : { type : string }
task_id : { type : string }
agent_session_id : { type : string }
thread_id : { type : string }
2026-10-14 09:40:12 -07:00
kind : { type : string, enum : [ question, report, session_error, rate_limited] }
2026-10-14 07:02:56 -07:00
priority : { type : string, enum : [ blocked, gate, review, fyi] }
blocking : { type : boolean }
payload :
type : object
description : >
2026-10-14 23:34:39 -07:00
question: context (Markdown with the choices inline as `- ( ) text` / `- (*) text` pick-one or `- [ ] text` / `- [x] text` pick-any list items),
question, why_blocked, options (each choice's text, in order), multiple (true for pick-any), recommended (the marked choices' text), attachments.
2026-10-14 19:35:34 -07:00
report: text (the final message of a turn that ended normally).
2026-10-14 07:02:56 -07:00
session_error: error.
2026-10-14 09:40:12 -07:00
rate_limited: vendor, rate_limit (the vendor's rate-limit status), error.
2026-10-14 07:02:56 -07:00
state : { $ref : "#/components/schemas/InboxState" }
created_at : { type : string, format : date-time }
resolved_by : { type : string }
resolved_at : { type : string, format : date-time }
responses :
type : array
items : { $ref : "#/components/schemas/InboxResponse" }
InboxResponseType :
type : string
2026-10-14 23:34:39 -07:00
enum : [ option, other, dismiss]
2026-10-14 07:02:56 -07:00
InboxResponse :
type : object
required : [ id, item_id, user, type, attachments, created_at]
properties :
id : { type : string }
item_id : { type : string }
user : { type : string }
type : { $ref : "#/components/schemas/InboxResponseType" }
2026-10-14 23:34:39 -07:00
options :
type : array
items : { type : string }
2026-10-14 07:02:56 -07:00
text : { type : string }
attachments :
type : array
items : { $ref : "#/components/schemas/Attachment" }
created_at : { type : string, format : date-time }
delivered_at : { type : string, format : date-time }
InboxResponseCreate :
type : object
required : [ item_id, type]
properties :
item_id : { type : string }
type : { $ref : "#/components/schemas/InboxResponseType" }
2026-10-14 23:34:39 -07:00
options :
type : array
items : { type : string }
description : "option: the chosen options; exactly one for a pick-one question, one or more for a pick-any question."
2026-10-14 23:54:13 -07:00
text : { type : string, description : "other: the text sent to the agent. option on a pick-any question: optional text sent along with the checked options." }
2026-10-14 07:02:56 -07:00
attachments :
type : array
items : { $ref : "#/components/schemas/Attachment" }
InboxRespond :
type : object
required : [ responses]
properties :
responses :
type : array
minItems : 1
items : { $ref : "#/components/schemas/InboxResponseCreate" }
2026-10-13 22:19:20 -07:00
Event :
type : object
required : [ seq, kind, actor, payload, created_at]
properties :
seq : { type : integer, format : int64 }
kind : { type : string }
project_id : { type : string }
task_id : { type : string }
2026-10-13 22:30:39 -07:00
agent_session_id : { type : string }
2026-10-15 09:40:30 -07:00
owner : { type : string, description : "Set on a lead agent's events and a user's focus.updated: the login they belong to. Only that user is sent them." }
2026-10-13 22:19:20 -07:00
actor : { type : string }
payload : { type : object }
created_at : { type : string, format : date-time }
2026-10-15 09:40:30 -07:00
Focus :
type : object
required : [ tabs, tab]
properties :
2026-10-15 09:59:13 -07:00
project_id : { type : string, description : The project the right pane shows; the task's project when task_id is set, absent for none. }
2026-10-15 09:40:30 -07:00
task_id : { type : string, description : The task the right pane shows; absent for none. }
tabs :
type : array
description : The tabs the lead put first, in order. The other task tabs follow them.
items : { $ref : "#/components/schemas/TaskTab" }
tab : { $ref : "#/components/schemas/TaskTab" }
2026-10-15 09:59:13 -07:00
PaneFocus :
type : object
required : [ focused]
properties :
focused : { type : boolean, description : True while the browser window has focus and the focused element is inside the right pane. }
2026-10-15 09:40:30 -07:00
TaskTab :
type : string
2026-10-15 10:36:32 -07:00
enum : [ transcript, changes, files, inbox, project]
x-enum-varnames : [ TabTranscript, TabChanges, TabFiles, TabInbox, TabProject]
2026-10-15 09:40:30 -07:00
2026-10-13 22:19:20 -07:00
Status :
type : object
2026-10-14 22:35:53 -07:00
required : [ started_at, db_bytes, last_event_seq, projects, active_tasks, sse_clients, live_agents, running_turns, queued_turns, caps, rate_limits, agent_processes, zombies, stuck_after_seconds, protocol_errors]
2026-10-13 22:19:20 -07:00
properties :
2026-10-13 22:30:39 -07:00
live_agents : { type : integer, description : Agent processes currently running. }
2026-10-14 22:35:53 -07:00
agent_processes :
type : array
description : Every agent process byre is tracking, idle sessions included.
items : { $ref : "#/components/schemas/AgentProcess" }
zombies :
type : array
description : Sessions marked running with no live process, and agent processes byre has no session for.
items : { $ref : "#/components/schemas/Zombie" }
stuck_after_seconds : { type : integer, description : How long a running turn may go without a stream event before it counts as stuck. }
protocol_errors : { $ref : "#/components/schemas/ProtocolErrors" }
2026-10-14 21:06:30 -07:00
running_turns :
type : array
description : Turns running now, oldest session first.
items : { $ref : "#/components/schemas/TurnRef" }
queued_turns :
type : array
description : Turns waiting for room under the caps, in the order they will start.
items : { $ref : "#/components/schemas/TurnRef" }
caps : { $ref : "#/components/schemas/Caps" }
2026-10-14 09:40:12 -07:00
rate_limits :
type : object
description : The latest rate-limit status each vendor reported, keyed by vendor.
additionalProperties : { type : object }
2026-10-13 22:19:20 -07:00
started_at : { type : string, format : date-time }
db_bytes : { type : integer, format : int64 }
last_event_seq : { type : integer, format : int64 }
projects : { type : integer }
active_tasks : { type : integer }
sse_clients : { type : integer }
2026-10-14 21:06:30 -07:00
Caps :
type : object
required : [ global, per_vendor]
properties :
global : { type : integer, description : Most turns running at once across all vendors. }
per_vendor :
type : object
description : Most turns running at once per vendor, keyed by vendor.
additionalProperties : { type : integer }
TurnRef :
type : object
required : [ session_id, task_id, vendor]
properties :
session_id : { type : string }
task_id : { type : string }
vendor : { type : string }
2026-10-14 22:35:53 -07:00
AgentProcess :
type : object
required : [ session_id, task_id, vendor, pid, state, last_event_at, health]
properties :
session_id : { type : string }
task_id : { type : string }
vendor : { type : string }
pid : { type : integer }
state : { type : string, description : The session's state, as on AgentSession. }
last_event_at : { type : string, format : date-time, description : When the process last wrote a line to its stream, or when it started. }
health :
type : string
enum : [ ok, stuck, exited]
x-enum-varnames : [ HealthOk, HealthStuck, HealthExited]
description : stuck means a turn is running and no stream event has arrived for stuck_after_seconds; exited means the process is gone.
Zombie :
type : object
required : [ kind, detail]
properties :
kind :
type : string
enum : [ running_without_process, process_without_session]
detail : { type : string }
session_id : { type : string }
task_id : { type : string }
pid : { type : integer }
ProtocolErrors :
type : object
required : [ counts, recent]
properties :
counts :
type : object
description : Stream lines the adapter couldn't parse or didn't recognise since byre started, keyed by vendor.
additionalProperties : { type : integer }
recent :
type : array
description : The most recent ones, newest first.
items : { $ref : "#/components/schemas/ProtocolError" }
ProtocolError :
type : object
required : [ vendor, session_id, at, reason, raw, size]
properties :
vendor : { type : string }
session_id : { type : string }
at : { type : string, format : date-time }
reason : { type : string }
raw : { type : string, description : The line as received, cut to its first 4 KiB. }
size : { type : integer, description : The line's full length in bytes. }