Artifact b094c40081557084feddb82fab0812c90d693bf594b7cbe59b3a8eec98f12e69:
- File
docs/api.md
— part of check-in
[f4e226e5a4]
at
2026-08-31 12:18:02
on branch trunk
— large files arrive: size-gate the highlighter and cache it by content
Highlighting was paid on every request with no cache, and its cost tracks token density: sqlite's btree.c, 407KB of dense C, took 490ms and rendered 2.3MB of HTML. Past 256KB the lexer is skipped and the page says so; below it, identical content is highlighted once. (user: quarry, size: 65567) [annotate] [blame] [check-ins using]
# quarry API Generated from the op registry by `quarry docs` — edit the ops, not this file; regenerate with `make docs`. Every op also appears in the OpenAPI document (`quarry spec`). Query inputs ride the query string; the same names work as JSON. ## account.add `POST /api/v1/accounts` — command, admin Create a forge account. The password is hashed with argon2id and never stored or returned in plaintext. Input: | field | type | rules | |---|---|---| | `name` | string | `required,max=64` | | `password` | string | `required,max=1024` | | `admin` | boolean | — | Output fields: - `name` (string) - `admin` (boolean) ## account.delete `POST /api/v1/accounts/delete` — command, admin Delete an account and all of its grants. Input: | field | type | rules | |---|---|---| | `name` | string | `required,max=64` | Output fields: - `name` (string) ## account.explain `GET /api/v1/accounts/explain` — query, admin Read one account's capability string on a repository as a role, the abilities that differ from it, and a sentence of what the person can do there (RFC 0008). Input: | field | type | rules | |---|---|---| | `name` | string | `required,max=64` | | `repo` | string | `required,max=64` | Output fields: - `name` (string) - `repo` (string) - `caps` (string) - `effective` (string) - `role` (string) - `exact` (boolean) - `plus` (array of string) - `minus` (array of string) - `can` (string) - `grants` (array of string) ## account.grant `POST /api/v1/accounts/grant` — command, admin Give an account a role on one repository: reader, developer, maintainer or admin (RFC 0008; read and write are accepted as older spellings of the first two). The role's capability string replaces any string the account held there. Input: | field | type | rules | |---|---|---| | `name` | string | `required,max=64` | | `repo` | string | `required,max=64` | | `role` | string | `required,oneof=read\|write\|admin\|reader\|developer\|maintainer` | Output fields: - `name` (string) - `repo` (string) - `role` (string) - `warning` (string) ## account.list `GET /api/v1/accounts` — query, admin List forge accounts and their per-repository grants. Output fields: - `accounts` (array of object {Account: object {name: string, admin: boolean, created: string}, grants: array of object {repo: string, role: string}}) - `count` (integer) ## account.passwd `POST /api/v1/accounts/passwd` — command, admin Set an account's password. Input: | field | type | rules | |---|---|---| | `name` | string | `required,max=64` | | `password` | string | `required,max=1024` | Output fields: - `name` (string) ## account.revoke `POST /api/v1/accounts/revoke` — command, admin Remove an account's grant on one repository. Input: | field | type | rules | |---|---|---| | `name` | string | `required,max=64` | | `repo` | string | `required,max=64` | Output fields: - `name` (string) - `repo` (string) - `role` (string) - `warning` (string) ## archive.get `GET /api/v1/r/{repo}/archive/{version}` — query, anonymous Download a check-in's files as a reproducible archive (tar.gz or zip). Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `version` | string | `max=100` | | `format` | string | `oneof=tar\|zip` | Output fields: - `name` (string) - `size` (integer) - `version` (string) - `content` (string) ## artifact.resolve `GET /api/v1/r/{repo}/info/{prefix}` — query, anonymous Resolve an artifact hash prefix to its kind and canonical reference — fossil's /info dispatch. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `prefix` | string | `required,min=4,max=64` | Output fields: - `kind` (string) - `ref` (string) ## attachment.get `GET /api/v1/r/{repo}/attachment/{hash}` — query, anonymous Fetch one attachment's content by its content-artifact hash. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `hash` | string | `required,min=4,max=64` | Output fields: - `name` (string) - `size` (integer) - `content` (string) ## attention.read `POST /api/v1/me/attention/read` — command, token Move the signed-in account's attention read pointer to seq (default: everything so far). Forward-only — a stale client replaying an old cursor cannot resurrect mail already dismissed. Input: | field | type | rules | |---|---|---| | `seq` | integer | — | Output fields: - `ok` (boolean) - `seq` (integer) ## branch.list `GET /api/v1/r/{repo}/branch` — query, anonymous List branches with their tip check-in, most recently active first. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | Output fields: - `branches` (array of object {name: string, tip: string, date: string, closed: boolean}) - `count` (integer) ## chat.delete `POST /api/v1/r/{repo}/chat/{seq}/delete` — command, token Delete a chat message: own with C, any message with a. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `seq` | integer | `required` | Output fields: - `ok` (boolean) - `seq` (integer) ## chat.edit `POST /api/v1/r/{repo}/chat/{seq}/edit` — command, token Edit a chat message posted within the last 5 minutes, own only. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `seq` | integer | `required` | | `text` | string | `required,max=4096` | Output fields: - `ok` (boolean) - `seq` (integer) ## chat.get `GET /api/v1/r/{repo}/chat/{seq}` — query, anonymous One folded chat message with its direct replies; the permalink. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `seq` | integer | `required` | Output fields: - `message` (object {seq: integer, kind: string, ref: integer, repo: string, user: string, text: string, origin: string, at: string, edited: boolean, deleted: boolean, html: string, refs: array of string, replies: integer, refUser: string, refLine: string}) - `replies` (array of object {seq: integer, kind: string, ref: integer, repo: string, user: string, text: string, origin: string, at: string, edited: boolean, deleted: boolean, html: string, refs: array of string, replies: integer, refUser: string, refLine: string}) - `expired` (boolean) ## chat.history `GET /api/v1/r/{repo}/chat` — query, anonymous Recent messages in a repository's chat channel, oldest first. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `before` | integer | — | | `limit` | integer | `min=0,max=500,default=100` | Output fields: - `messages` (array of object {seq: integer, kind: string, ref: integer, repo: string, user: string, text: string, origin: string, at: string, edited: boolean, deleted: boolean, html: string, refs: array of string, replies: integer, refUser: string, refLine: string}) - `count` (integer) - `next` (integer) - `read` (integer) ## chat.post `POST /api/v1/r/{repo}/chat` — command, token Post a message to a repository's chat channel. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `text` | string | `required,max=4096` | | `ref` | integer | — | Output fields: - `ok` (boolean) - `seq` (integer) ## chat.read `POST /api/v1/r/{repo}/chat/read` — command, token Mark a repository's chat channel read up to seq (default: latest). Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `seq` | integer | — | Output fields: - `ok` (boolean) - `seq` (integer) ## chat.robot `POST /api/v1/r/{repo}/chat/robot` — command, token Set which events the activity robot announces in a repository's chat channel, in the webhook pattern syntax (`*`, a noun like `checkin`, or an exact kind like `landing.accepted`), space-separated. Empty turns the robot off. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `events` | string | `max=512` | Output fields: - `repo` (string) - `events` (string) - `on` (boolean) ## chat.robot.get `GET /api/v1/r/{repo}/chat/robot` — query, token The repository's activity-robot event patterns; empty when the robot is off. Its own op rather than a field on repo.get, because it is chat configuration and only an administrator may see it. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | Output fields: - `repo` (string) - `events` (string) - `on` (boolean) ## chat.stream `GET /api/v1/r/{repo}/chat/stream` — stream, anonymous Live chat messages as Server-Sent Events. The body is text/event-stream, not JSON: each event's `id:` line is the message's stream sequence, and a client that reconnects with `Last-Event-ID: <seq>` resumes after it. A resume older than the window replays from the window's first message, preceded by an `event: gap` frame carrying {"from":<asked>,"first":<available>} so a renderer re-renders rather than appends. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `from` | integer | — | Output fields: - `seq` (integer) - `kind` (string) - `ref` (integer) - `repo` (string) - `user` (string) - `text` (string) - `origin` (string) - `at` (string) - `edited` (boolean) - `deleted` (boolean) - `html` (string) - `refs` (array of string) - `replies` (integer) - `refUser` (string) - `refLine` (string) ## chat.unread `GET /api/v1/me/chat/unread` — query, token Per-repository unread chat counts for the signed-in account. Output fields: - `repos` (map) ## check.report `POST /api/v1/r/{repo}/checks` — command, anonymous Report an external check's state onto a check-in — the commit-status contract, quarry-shaped (RFC 0009 §external-ci). Authenticated by a reporter token minted in the repository's CI settings; the token reaches this op and nothing else. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `checkin` | string | `required,min=4,max=200` | | `context` | string | `required,max=100` | | `state` | string | `required,oneof=pending\|success\|failure\|error` | | `url` | string | `max=300` | | `summary` | string | `max=2048` | | `token` | string | `required,max=128` | Output fields: - `ok` (boolean) - `context` (string) - `state` (string) ## checkin.diff `GET /api/v1/r/{repo}/checkin/{hash}/diff` — query, anonymous Diff one check-in against its primary parent. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `hash` | string | `required,min=4,max=64` | | `file` | string | `max=4096` | | `offset` | integer | `min=0` | | `maxLines` | integer | `min=0` | | `branch` | boolean | — | | `from` | string | `max=64` | | `unified` | boolean | — | Output fields: - `from` (string) - `to` (string) - `files` (array of object {status: string, name: string}) - `structured` (array of object {path: string, prevPath: string, change: string, hunks: array of object {oldStart: integer, newStart: integer, header: string, lines: array of object {kind: string, oldNum: integer, newNum: integer, tokens: array of object {class: string, text: string, mark: boolean}}}, added: integer, deleted: integer, before: integer, omitted: integer}) - `unified` (string) - `note` (string) - `omittedLines` (integer) - `nextOffset` (integer) - `totalLines` (integer) - `lastOffset` (integer) - `offset` (integer) ## checkin.get `GET /api/v1/r/{repo}/checkin/{hash}` — query, anonymous Describe one check-in: metadata, parents, and its file set. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `hash` | string | `required,min=4,max=64` | | `files` | string | `max=4` | Output fields: - `hash` (string) - `ci` (string) - `ciRun` (string) - `branch` (string) - `date` (string) - `user` (string) - `comment` (string) - `parents` (array of string) - `files` (array of object {blob: string, name: string, size: integer, perm: string, binary: boolean}) - `discussedIn` (array of object {root: string, title: string, posts: integer, created: string, updated: string, user: string, excerpt: string, hasPoll: boolean, participants: array of string, dates: array of string}) - `chatRefs` (object {count: integer, seq: integer, at: string}) - `tags` (array of string) - `commentOrig` (string) - `hidden` (boolean) - `closed` (boolean) - `fork` (string) - `context` (array of object {kind: string, hash: string, ref: string, date: string, user: string, comment: string, branch: string, isLeaf: boolean, isMerge: boolean, parents: array of string, ci: string, commentOrig: string, hidden: boolean, closed: boolean, landing: string, landingTitle: string, landingApprover: string, excerpt: string}) ## checkin.manifest `GET /api/v1/r/{repo}/checkin/{hash}/manifest` — query, anonymous One check-in's manifest artifact, as cards. The file list is counted, not returned — it is 99% of the bytes and the tree browser already renders it. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `hash` | string | `required,min=4,max=64` | Output fields: - `hash` (string) - `size` (integer) - `cards` (array of object {letter: string, text: string, note: string}) - `files` (integer) ## checkin.tags `GET /api/v1/r/{repo}/checkin/{hash}/tags` — query, anonymous The full tag history of a check-in — every tag artifact that touched it, oldest first, with which rows still stand. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `hash` | string | `required,min=4,max=64` | Output fields: - `hash` (string) - `date` (string) - `user` (string) - `comment` (string) - `commentOrig` (string) - `branch` (string) - `hidden` (boolean) - `closed` (boolean) - `events` (array of object {date: string, src: string, name: string, sign: string, value: string, standing: boolean}) ## ci.list `GET /api/v1/r/{repo}/ci` — query, anonymous List a repository's CI runs, newest first. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `limit` | integer | `min=0,max=200,default=50` | Output fields: - `runs` (array of object {url: string, runId: string, checkin: string, pair: string, workflow: string, pipeline: string, status: string, started: string, completed: string, branch: string, comment: string, user: string}) - `count` (integer) - `bypasses` (array of object {repo: string, branch: string, checkin: string, seen: string}) ## ci.pipeline.save `POST /api/v1/r/{repo}/ci/pipeline` — command, token Validate a pipeline, or commit it to a fresh branch and open a landing. Never writes to the target branch: a pipeline edit lands like any other change. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `path` | string | `required,max=120` | | `content` | string | `required,max=262144` | | `message` | string | `max=500` | | `validate` | boolean | — | Output fields: - `diagnostics` (array of string) - `hash` (string) - `branch` (string) - `landing` (string) ## ci.token.list `GET /api/v1/r/{repo}/ci/tokens` — query, admin List a repository's reporter tokens: labels, creation times and hashes — never the tokens. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | Output fields: - `tokens` (array of object {hash: string, label: string, created: string}) - `count` (integer) ## ci.token.new `POST /api/v1/r/{repo}/ci/tokens` — command, admin Mint a reporter token for external CI on one repository. The token is returned once and never stored; only its hash is kept. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `label` | string | `max=100` | Output fields: - `token` (string) ## ci.token.revoke `POST /api/v1/r/{repo}/ci/tokens/revoke` — command, admin Revoke one reporter token by its stored hash, returning the remaining list. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `hash` | string | `required,max=64` | Output fields: - `tokens` (array of object {hash: string, label: string, created: string}) - `count` (integer) ## ci.trigger `POST /api/v1/r/{repo}/ci/trigger` — command, token Run a repository's pipelines now, at a check-in or the tip (RFC 0009 §triggers). The re-run button; deploys and nightlies by hand. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `checkin` | string | `max=64` | Output fields: - `ok` (boolean) ## config.import `POST /api/v1/r/{repo}/config/import` — command, admin Apply a fossil configuration-area export file to a store — replace (import) or fold (merge), as the file's cards decide (RFC 0008 rung 8). supported=false until zit#153. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `file` | string | `required,max=8388608` | | `merge` | boolean | — | Output fields: - `supported` (boolean) - `note` (string) - `settings` (array of object {name: string, value: string, versionable: boolean}) ## doc.get `GET /api/v1/r/{repo}/doc/{hash}/{path...}` — query, anonymous Render one file from the tree as embedded documentation, chosen by extension. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `hash` | string | `required,min=1,max=64` | | `path` | string | `required,max=512` | Output fields: - `hash` (string) - `path` (string) - `size` (integer) - `mimetype` (string) - `html` (string) - `outline` (array of object {level: integer, id: string, text: string}) - `contentType` (string) - `content` (string) ## doc.list `GET /api/v1/r/{repo}/doc` — query, anonymous List the documents in a check-in's conventional documentation directories. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `version` | string | `max=64` | Output fields: - `version` (string) - `docs` (array of object {path: string, size: integer, date: string, user: string}) ## file.get `GET /api/v1/r/{repo}/file/{hash}/{path...}` — query, anonymous Fetch one file's content at a check-in. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `hash` | string | `required,min=4,max=64` | | `path` | string | `required,max=512` | Output fields: - `hash` (string) - `path` (string) - `size` (integer) - `binary` (boolean) - `content` (string) - `html` (string) - `renderable` (boolean) - `plain` (string) ## file.history `GET /api/v1/r/{repo}/history/{version}/{path...}` — query, anonymous List the check-ins that changed one file, newest first. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `version` | string | `max=100` | | `path` | string | `required,max=1024` | | `limit` | integer | `min=0,max=200,default=50` | Output fields: - `path` (string) - `version` (string) - `changes` (array of object {hash: string, date: string, user: string, comment: string}) - `count` (integer) ## fleet.status `GET /api/v1/fleet` — query, admin Report every served store's ingest health. Output fields: - `repos` (array of object {name: string, code: string, checkins: integer, indexing: boolean, health: object {lastOk: string, roundSeconds: number, lastCount: integer, total: integer, fallbacks: integer, gaps: integer, lastErr: string, lastErrAt: string, failures: integer, stalled: boolean, retryAt: string}}) - `count` (integer) - `unhealthy` (integer) - `errors` (array of object {message: string, surface: string, path: string, count: integer, first: object {}, last: object {}, repo: string, trace: string}) - `errorTotal` (integer) ## fleet.sync `POST /api/v1/fleet/sync` — command, admin Run an ingest round now — one store, or every store when `repo` is empty. Input: | field | type | rules | |---|---|---| | `repo` | string | `max=64` | Output fields: - `results` (array of object {repo: string, artifacts: integer, err: string}) - `failed` (integer) ## forum.get `GET /api/v1/r/{repo}/forum/{root}` — query, anonymous Fetch one forum thread: every post, rendered, in reading order. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `root` | string | `required,min=4,max=64` | Output fields: - `root` (string) - `title` (string) - `excerpt` (string) - `posts` (array of object {hash: string, parent: string, date: string, user: string, html: string, score: integer, yourVote: integer, hidden: boolean, hiddenReason: string, poll: object {present: boolean, question: string, options: array of string, counts: array of integer, percents: array of integer, total: integer, yourChoice: integer, closed: boolean, closes: string}}) - `yourSub` (string) - `chatRefs` (object {count: integer, seq: integer, at: string}) ## forum.list `GET /api/v1/r/{repo}/forum` — query, anonymous List a repository's forum threads, most-recently-active first. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `sort` | string | `max=8` | Output fields: - `threads` (array of object {ForumThread: object {root: string, title: string, posts: integer, created: string, updated: string, user: string, excerpt: string, hasPoll: boolean, participants: array of string, dates: array of string}, score: integer, category: string, spark: array of integer, read: boolean}) - `announcements` (array of object {ForumThread: object {root: string, title: string, posts: integer, created: string, updated: string, user: string, excerpt: string, hasPoll: boolean, participants: array of string, dates: array of string}, score: integer, category: string, spark: array of integer, read: boolean}) - `count` (integer) ## forum.post `POST /api/v1/r/{repo}/forum` — command, token Open a new forum thread. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `title` | string | `required,max=200` | | `body` | string | `required,max=1048576` | | `mimetype` | string | `max=64` | Output fields: - `hash` (string) - `staged` (boolean) ## forum.reply `POST /api/v1/r/{repo}/forum/{root}` — command, token Reply to a forum post within its thread. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `root` | string | `required,min=4,max=64` | | `to` | string | `max=64` | | `body` | string | `required,max=1048576` | | `mimetype` | string | `max=64` | Output fields: - `hash` (string) - `staged` (boolean) ## inbox.count `GET /api/v1/me/inbox/count` — query, token How much is waiting for the signed-in account: the unread notify inbox PLUS the local attention events after the account's read pointer that notify holds no copy of. When notify is configured every person-addressed event is written to BOTH halves, so the two are paired on the idempotency key quarry set on each and a paired event is counted once — under notify's read state, which is the one `inbox.list` renders. The pairing is read off a bounded page of each half; a local backlog deeper than that page is counted whole rather than silently dropped. A forge with no notify companion counts only the attention stream. Output fields: - `unread` (integer) ## inbox.list `GET /api/v1/me/inbox` — query, token One page of everything addressed to the signed-in account, newest first, merging the notify inbox with quarry's own attention stream. Each row carries a `reason` (mention, reply, landing, activity) derived from the workflow that sent it, and an `id` that `inbox.mark` takes back — a notify message id, or `local:<seq>` for an attention event. An event quarry raised while notify was configured exists in both halves; the two are paired on the idempotency key each carries and render as ONE row, notify's, whose id names both halves so a single mark reaches both. `before` is the opaque `next` cursor from a previous page; it addresses BOTH sources at once, so a row the page limit cut off is served by the next page rather than skipped. Input: | field | type | rules | |---|---|---| | `before` | string | `max=1024` | | `limit` | integer | `min=0,max=200` | Output fields: - `rows` (array of object {id: string, source: string, reason: string, repo: string, from: string, summary: string, link: string, at: string, read: boolean, seq: integer}) - `next` (string) - `read` (integer) ## inbox.mark `POST /api/v1/me/inbox/mark` — command, token Mark inbox rows read, or done (archived — off the list). Takes the ids `inbox.list` gave, or `all` for the whole inbox. Ids reach notify; `local:<seq>` ids advance the account's attention read pointer, the same forward-only pointer `attention.read` moves, so clearing the inbox clears the badge whichever half a row came from. Input: | field | type | rules | |---|---|---| | `ids` | array of string | `max=500` | | `all` | boolean | — | | `as` | string | `oneof=read\|done,max=8` | Output fields: - `ok` (boolean) - `seq` (integer) ## inbox.recent `GET /api/v1/me/inbox/recent` — query, token What was recently addressed to the signed-in account, newest first, with their read pointer. This is the local attention window — the same events me.attention streams — so an inbox is a page a forge with no notify companion still renders correctly. Input: | field | type | rules | |---|---|---| | `limit` | integer | `min=0,max=200` | Output fields: - `events` (array of object {seq: integer, kind: string, repo: string, from: string, summary: string, link: string, at: string}) - `read` (integer) ## landing.accept `POST /api/v1/r/{repo}/landing/{id}/accept` — command, token Land the branch on its target and settle the record. Writes a merge check-in, so it needs the check-in capability rather than the forum one. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `id` | string | `required,min=4,max=64` | | `message` | string | `max=65536` | | `to` | string | `max=64` | | `override` | string | `max=2048` | Output fields: - `hash` (string) - `state` (string) ## landing.auto `POST /api/v1/r/{repo}/landing/{id}/auto` — command, token Arm or disarm auto-land: an armed open landing accepts itself once every required check on its target is green. The deferred accept is the ordinary one, written as the arming account. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `id` | string | `required,min=4,max=64` | | `on` | boolean | — | Output fields: - `autoBy` (string) ## landing.comment `POST /api/v1/r/{repo}/landing/{id}/comment` — command, token Add a remark to a landing's discussion. An ordinary forum reply. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `id` | string | `required,min=4,max=64` | | `message` | string | `max=65536` | | `to` | string | `max=64` | | `override` | string | `max=2048` | Output fields: - `hash` (string) - `state` (string) ## landing.get `GET /api/v1/r/{repo}/landing/{id}` — query, anonymous One landing: the record, its discussion, and whether the caller may accept it. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `id` | string | `required,min=4,max=64` | Output fields: - `landing` (object {id: string, branch: string, target: string, title: string, author: string, opened: string, updated: string, state: string, settled_by: string, replies: integer, superseded_by: string, claimed_by: string, ci: string, stack: string, position: integer, depth: integer, broken: string}) - `checks` (array of object {url: string, runId: string, checkin: string, pair: string, workflow: string, pipeline: string, status: string, started: string, completed: string, branch: string, comment: string, user: string}) - `required` (array of string) - `premerge` (boolean) - `behind` (integer) - `unmet` (array of string) - `mayOverride` (boolean) - `autoBy` (string) - `posts` (array of object {transition: string, updated: string, retarget: string, titleIsBody: boolean, root: boolean}) - `chatRefs` (object {count: integer, seq: integer, at: string}) - `canAccept` (boolean) - `mergeable` (string) - `conflicts` (array of string) - `merge` (object {checkin: string, date: string, user: string, comment: string}) - `mergeCi` (string) - `mergeCiRun` (string) - `stack` (object {base: string, top: string, ci: string, segments: array of object {id: string, title: string, branch: string, target: string, state: string, position: integer, landable: boolean, ci: string}, broken: string}) - `mayLand` (boolean) - `protected` (boolean) - `owners` (array of string) - `commits` (array of object {hash: string, date: string, user: string, comment: string}) ## landing.land `POST /api/v1/r/{repo}/landing/{id}/land` — command, token Land a strata bottom-up, up to and including the named rung. Each rung is an ordinary accept; zit retargets the next; the first rung that will not merge stops the walk and is reported, with everything below it landed. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `id` | string | `required,min=4,max=64` | | `message` | string | `max=65536` | Output fields: - `landed` (array of string) - `stopped` (string) - `reason` (string) - `remaining` (integer) ## landing.list `GET /api/v1/r/{repo}/landing` — query, anonymous Landings in this repository: branches proposed to land on a target, newest activity first. A landing is a forum thread, so it reads on the forum capability. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `state` | string | `max=16` | | `limit` | integer | `min=0,max=200,default=50` | Output fields: - `landings` (array of object {id: string, branch: string, target: string, title: string, author: string, opened: string, updated: string, state: string, settled_by: string, replies: integer, superseded_by: string, claimed_by: string, ci: string, stack: string, position: integer, depth: integer, broken: string}) - `open` (integer) - `count` (integer) ## landing.open `POST /api/v1/r/{repo}/landing` — command, token Propose a branch to land on a target. Mints a forum thread — no new artifact kind — so a stock fossil clone reads it as an ordinary discussion. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `branch` | string | `required,max=120` | | `target` | string | `max=120` | | `message` | string | `required,max=65536` | Output fields: - `id` (string) ## landing.reject `POST /api/v1/r/{repo}/landing/{id}/reject` — command, token Settle a landing without merging. Writes no check-in, so it needs only the capability to speak in the thread. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `id` | string | `required,min=4,max=64` | | `message` | string | `max=65536` | | `to` | string | `max=64` | | `override` | string | `max=2048` | Output fields: - `hash` (string) - `state` (string) ## landing.update `POST /api/v1/r/{repo}/landing/{id}/update` — command, token Bring the target into the proposed branch, on the store, as a merge check-in (zit#152). Refused when the merge would not be clean; nothing is written. Writes to the PROPOSED branch, so it needs the check-in capability but not ownership of a protected target: membership of the target does not change. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `id` | string | `required,min=4,max=64` | | `message` | string | `max=65536` | | `to` | string | `max=64` | | `override` | string | `max=2048` | Output fields: - `hash` (string) - `state` (string) ## markup.preview `POST /api/v1/r/{repo}/markup-preview` — command, token Render markdown exactly as saving it would — the composer's preview IS the production renderer, so what you see is what readers get. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `body` | string | `max=1048576` | Output fields: - `html` (string) ## me.attention `GET /api/v1/me/attention` — stream, token Everything addressed to the signed-in account, as Server-Sent Events. The body is text/event-stream, not JSON: each event's `id:` line is its stream sequence, and a client that reconnects with `Last-Event-ID: <seq>` resumes after it. A resume older than the window replays from the window's first event, preceded by an `event: gap` frame carrying {"from":<asked>,"first":<available>}. Input: | field | type | rules | |---|---|---| | `from` | integer | — | Output fields: - `seq` (integer) - `kind` (string) - `repo` (string) - `from` (string) - `summary` (string) - `link` (string) - `at` (string) ## me.feed `GET /api/v1/me/feed` — query, token The signed-in dashboard: the caller's granted repositories ordered by activity, the merged activity feed across them, and the caller's own recorded work. Input: | field | type | rules | |---|---|---| | `kind` | string | `max=2` | | `offset` | integer | `min=0,max=1000` | | `find` | string | `max=64` | Output fields: - `user` (string) - `repos` (array of object {name: string, description: string, lastActivity: string, open: integer}) - `feed` (array of object {repo: string, kind: string, ref: string, hash: string, date: string, user: string, comment: string}) - `kinds` (array of object {kind: string, count: integer}) - `total` (integer) - `depth` (integer) - `mine` (array of object {repo: string, kind: string, ref: string, hash: string, date: string, user: string, comment: string}) ## me.prefs `GET /api/v1/me/prefs` — query, token The signed-in account's notification preferences: RFC 0011 §6's family x channel matrix ({mention, reply, landing, activity} x {inapp, push, email}) as notify holds it, plus the forge-local switches quarry owns — in-page toasts, desktop notifications, the repositories this account muted, and the browsers push was enabled in. A channel with no stored preference is ON, which is notify's own rule. Output fields: - `families` (map) - `channels` (array of string) - `toasts` (boolean) - `notify_desktop` (boolean) - `muted` (array of string) - `unknown` (array of string) - `devices` (array of object {endpoint_hash: string, ua: string, at: string, pending_remote_delete: boolean}) - `push` (boolean) - `applied` (object {local: boolean, notify: boolean}) ## me.prefs.set `POST /api/v1/me/prefs` — command, token Update the signed-in account's preferences. Each family carries the channels that stay ON (repeat the key), so the whole matrix is posted and an absent channel is off. The two forge-local switches are EXPLICIT — `toasts` and `notify_desktop` take "on" or "off", and leaving one out changes it not at all. `mute` and `unmute` are list operations for the same reason: naming neither changes no mute. A muted repository still reaches the account's own inbox, it just stops being sent. The answer's `applied` says which halves landed: the forge-local one always does, the notify one does not on a companion that did not answer its preferences route. Input: | field | type | rules | |---|---|---| | `mention` | array of string | `max=8` | | `reply` | array of string | `max=8` | | `landing` | array of string | `max=8` | | `activity` | array of string | `max=8` | | `toasts` | string | `oneof=on\|off,max=8` | | `notify_desktop` | string | `oneof=on\|off,max=8` | | `mute` | array of string | `max=200` | | `unmute` | array of string | `max=200` | Output fields: - `families` (map) - `channels` (array of string) - `toasts` (boolean) - `notify_desktop` (boolean) - `muted` (array of string) - `unknown` (array of string) - `devices` (array of object {endpoint_hash: string, ua: string, at: string, pending_remote_delete: boolean}) - `push` (boolean) - `applied` (object {local: boolean, notify: boolean}) ## me.push.key `GET /api/v1/me/push/key` — query, token notify's VAPID application-server public key, base64url — what a browser passes to pushManager.subscribe. Empty when this forge has no notify companion, which a page reads as "push is not available here". quarry never holds the private half. Output fields: - `publicKey` (string) ## me.push.subscribe `POST /api/v1/me/push` — command, token Register a browser for push. The body is the browser's own PushSubscription JSON ({endpoint, keys:{p256dh, auth}}), forwarded to notify as subscriber credentials for the webpush provider. quarry stores no endpoint and no key — only a hash, a user-agent label and a timestamp, so the preferences page can list the devices somebody may want to turn off. Also sweeps this account's unconfirmed unsubscribes: a device notify would not drop earlier is retried here, which is the one moment quarry knows the companion is reachable. Input: | field | type | rules | |---|---|---| | `endpoint` | string | `required,max=2048` | | `keys` | object {p256dh: string, auth: string} | — | | `ua` | string | `max=256` | Output fields: - `ok` (boolean) - `devices` (array of object {endpoint_hash: string, ua: string, at: string, pending_remote_delete: boolean}) - `pending_remote_delete` (boolean) ## me.push.unsubscribe `POST /api/v1/me/push/delete` — command, token Stop pushing to one browser: drops the endpoint's credential in notify and forgets the device row. A credential notify does not hold (404) and one the push service already discarded (410 Gone) are both done, since that is the end state asked for. A notify that FAILED the delete has not dropped anything, so quarry keeps the device row marked `pending_remote_delete`, holding the endpoint only until the delete can be confirmed, and retries on the next `me.push.subscribe`. Forgetting the row on an unconfirmed delete is how a phone keeps buzzing with nothing left in the interface to stop it. Input: | field | type | rules | |---|---|---| | `endpoint` | string | `required,max=2048` | Output fields: - `ok` (boolean) - `devices` (array of object {endpoint_hash: string, ua: string, at: string, pending_remote_delete: boolean}) - `pending_remote_delete` (boolean) ## meta.docs `GET /api/v1/docs` — query, anonymous The API reference, generated from this registry and rendered. Output fields: - `markdown` (string) - `html` (string) ## meta.version `GET /api/v1/version` — query, anonymous Report the quarry build version. Output fields: - `version` (string) ## mirror.chatbridge `POST /api/v1/r/{repo}/mirror/chatbridge` — command, admin Bridge a repository's chat channel to a Fossil server's chat, or detach it. The password is stored and never returned. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `url` | string | `max=512` | | `user` | string | `max=64` | | `password` | string | `max=256` | | `detach` | boolean | — | Output fields: - `bridge` (object {repo: string, url: string, user: string, lastMsgId: integer, at: string, lastErr: string}) - `detached` (boolean) ## mirror.detach `POST /api/v1/mirrors/detach` — command, admin Detach a store from its upstream: quarry becomes the source of truth and accepts writes; the upstream is kept as provenance (`detachedFrom`). Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | Output fields: - `repo` (string) ## mirror.list `GET /api/v1/mirrors` — query, admin List configured upstream mirrors and their recent history. Output fields: - `mirrors` (array of object {repo: string, url: string, every: integer, enabled: boolean, lastAt: string, lastOk: string, lastErr: string, failures: integer, acceptWrites: boolean, detachedFrom: string, state: string, bridged: boolean, chatBridge: object {repo: string, url: string, user: string, lastMsgId: integer, at: string, lastErr: string}}) - `count` (integer) ## mirror.run `POST /api/v1/mirrors/run` — command, admin Pull from upstream now — one store, or every configured mirror when `repo` is empty. Input: | field | type | rules | |---|---|---| | `repo` | string | `max=64` | Output fields: - `results` (array of object {repo: string, changed: boolean, err: string}) - `failed` (integer) - `changed` (integer) ## mirror.set `POST /api/v1/mirrors` — command, admin Configure a store's upstream and pull interval. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `url` | string | `required,max=2048` | | `every` | integer | `min=0,max=604800,default=3600` | Output fields: - `mirror` (object {repo: string, url: string, every: integer, enabled: boolean, lastAt: string, lastOk: string, lastErr: string, failures: integer, acceptWrites: boolean, detachedFrom: string, state: string, bridged: boolean, chatBridge: object {repo: string, url: string, user: string, lastMsgId: integer, at: string, lastErr: string}}) ## mirror.writes `POST /api/v1/mirrors/writes` — command, admin Allow or refuse local writes (push, tickets, wiki, forum) on a mirror. Refused by default: a write landing on a tracking store forks it by accident. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `accept` | boolean | — | Output fields: - `mirror` (object {repo: string, url: string, every: integer, enabled: boolean, lastAt: string, lastOk: string, lastErr: string, failures: integer, acceptWrites: boolean, detachedFrom: string, state: string, bridged: boolean, chatBridge: object {repo: string, url: string, user: string, lastMsgId: integer, at: string, lastErr: string}}) ## ops.history `GET /api/v1/ops/history` — query, admin Renders read back from the durable analytics store, newest or slowest first. Input: | field | type | rules | |---|---|---| | `find` | string | `max=200` | | `repo` | string | `max=64` | | `sort` | string | `oneof=recent\|slowest` | | `days` | integer | `min=0,max=90,default=14` | | `limit` | integer | `min=0,max=500,default=100` | Output fields: - `rows` (array of object {at: string, path: string, url: string, repo: string, elapsedMs: integer, opsMs: integer, zitMs: integer, status: integer}) - `find` (string) - `repo` (string) - `sort` (string) - `days` (integer) - `store` (object {configured: boolean, path: string, err: string, kept: string}) ## ops.route `GET /api/v1/ops/route` — query, admin One route's recent renders, split by repository, with the store calls each one made. Input: | field | type | rules | |---|---|---| | `path` | string | `required,max=200` | | `limit` | integer | `min=0,max=100,default=20` | | `days` | integer | `min=0,max=90,default=14` | Output fields: - `path` (string) - `renders` (array of object {at: string, repo: string, elapsedMs: integer, opsMs: integer, zitMs: integer, status: integer, calls: array of object {verb: string, repo: string, durationMs: integer}, callMs: integer}) - `byRepo` (array of object {repo: string, count: integer, p50Ms: integer, maxMs: integer}) - `trend` (array of object {day: string, n: integer, p50Ms: integer, p95Ms: integer, maxMs: integer}) - `trendDays` (integer) ## ops.status `GET /api/v1/ops` — query, admin Operational analytics: slowest routes, recent renders, store subprocess load. Input: | field | type | rules | |---|---|---| | `limit` | integer | `min=0,max=200,default=25` | | `find` | string | `max=200` | | `sort` | string | `oneof=p95\|p50\|max\|n\|path` | Output fields: - `phase` (object {name: string, repos: integer, ready: integer, working: array of string, stalled: array of string, artifacts: integer, slowestRoundSeconds: number}) - `paths` (array of object {path: string, count: integer, p50Ms: integer, p95Ms: integer, maxMs: integer}) - `renders` (array of object {at: string, path: string, url: string, repo: string, elapsedMs: integer, opsMs: integer, zitMs: integer, status: integer}) - `verbs` (array of object {verb: string, count: integer, totalMs: integer, maxMs: integer}) - `liveSubprocess` (integer) - `peakSubprocess` (integer) - `errorTotal` (integer) - `budgetMs` (integer) - `store` (object {configured: boolean, path: string, err: string, kept: string}) ## people.list `GET /api/v1/people` — query, anonymous List contributors across every repository the caller may read. Input: | field | type | rules | |---|---|---| | `repo` | string | `max=64` | | `q` | string | `max=100` | | `offset` | integer | `min=0,max=1000000` | | `limit` | integer | `min=0,max=500,default=100` | Output fields: - `people` (array of object {user: string, events: integer, first: string, last: string, repos: array of string}) - `count` (integer) - `total` (integer) ## people.mention `GET /api/v1/r/{repo}/mention` — query, token Handles with any capability on this repository, for @ completion. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `q` | string | `max=64` | Output fields: - `handles` (array of object {handle: string, caps: string}) ## ref.resolve `GET /api/v1/r/{repo}/ref` — query, anonymous Resolve one reference token to the facts a preview card shows. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `ref` | string | `required,max=512` | Output fields: - `kind` (string) - `id` (string) - `repo` (string) - `title` (string) - `summary` (string) - `state` (string) - `href` (string) - `expired` (boolean) - `author` (string) - `at` (string) ## repo.about `GET /api/v1/r/{repo}/about` — query, anonymous The repository's About aggregate: description, homepage and topics (.quarry/repo.json), the landing page's document tabs, the latest release tag, and the contributor count. One op so the panel costs one invoke and the JSON API sees the same panel. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `doc` | string | `max=512` | Output fields: - `docPath` (string) - `docLabel` (string) - `docHtml` (string) - `description` (string) - `homepage` (string) - `topics` (array of string) - `docs` (array of object {path: string, label: string}) - `latestTag` (string) - `latestTagTip` (string) - `latestTagDate` (string) - `tagCount` (integer) - `contributors` (integer) - `licenseName` (string) - `announceRoot` (string) - `announceTitle` (string) - `announceDate` (string) - `noteEvent` (string) - `noteTitle` (string) - `noteDate` (string) - `noteUser` (string) - `noteExcerpt` (string) - `noteCount` (integer) - `problem` (string) ## repo.add `POST /api/v1/repos` — command, admin Serve a repository: an existing store at `path`, a new empty one (`create`), or a clone of `clone`. Cloning also records a mirror unless `noMirror`. Input: | field | type | rules | |---|---|---| | `name` | string | `required,max=64` | | `path` | string | `max=4096` | | `description` | string | `max=300` | | `private` | boolean | — | | `create` | boolean | — | | `clone` | string | `max=2048` | | `readme` | boolean | — | | `license` | string | `max=16` | | `ignore` | boolean | — | | `noMirror` | boolean | — | | `mirrorEvery` | integer | `min=0,max=604800` | Output fields: - `name` (string) - `path` (string) - `mirrored` (boolean) ## repo.counts `GET /api/v1/r/{repo}/counts` — query, anonymous Count a repository's content by section — what the navigation shows. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | Output fields: - `indexBehind` (boolean) - `checkins` (integer) - `wikiPages` (integer) - `tickets` (integer) - `forumThreads` (integer) - `openLandings` (integer) - `technotes` (integer) - `contributors` (integer) - `tags` (integer) ## repo.delete `POST /api/v1/repos/delete` — command, admin Destroy a repository: its store, its index and everything keyed to it. `confirm` must equal `name`. Only repositories quarry created can be deleted. Input: | field | type | rules | |---|---|---| | `name` | string | `required,max=64` | | `confirm` | string | `required,max=64` | Output fields: - `name` (string) ## repo.get `GET /api/v1/r/{repo}/info` — query, anonymous Describe one repository: its settings and headline counts. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | Output fields: - `name` (string) - `visibility` (string) - `contributors` (integer) - `mirroredAt` (string) - `mirror` (object {tracking: boolean, url: string, every: integer, lastOk: string, lastAt: string, lastErr: string, failures: integer, acceptWrites: boolean, state: string}) - `detachedFrom` (string) - `deletable` (boolean) - `homepage` (string) - `topics` (string) - `fossilClone` (boolean) - `lastActive` (string) - `description` (string) - `private` (boolean) - `checkins` (integer) - `tipDate` (string) - `tipComment` (string) - `indexing` (boolean) ## repo.imports `GET /api/v1/repos/imports` — query, admin Repositories being copied from an upstream, and ones whose copy failed. Output fields: - `imports` (array of object {name: string, url: string, state: string, error: string, started: string, bytes: integer}) - `count` (integer) ## repo.list `GET /api/v1/repos` — query, anonymous List the served repositories with their tip check-in. Input: | field | type | rules | |---|---|---| | `q` | string | `max=64` | | `sort` | string | `oneof=active\|name\|size` | | `limit` | integer | `min=0,max=500` | | `kind` | string | `oneof=\|mirror\|native` | Output fields: - `repos` (array of object {name: string, visibility: string, contributors: integer, mirroredAt: string, mirror: object {tracking: boolean, url: string, every: integer, lastOk: string, lastAt: string, lastErr: string, failures: integer, acceptWrites: boolean, state: string}, detachedFrom: string, deletable: boolean, homepage: string, topics: string, fossilClone: boolean, lastActive: string, description: string, private: boolean, checkins: integer, tipDate: string, tipComment: string, indexing: boolean}) - `count` (integer) - `total` (integer) - `served` (integer) ## repo.reindex `POST /api/v1/r/{repo}/reindex` — command, admin Wipe this repository's derived index and replay it from the store, in process, while the forge serves. The sanctioned repair for any index that disagrees with its store. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | Output fields: - `artifacts` (integer) ## repo.remove `POST /api/v1/repos/remove` — command, admin Stop serving a repository. The store on disk is left untouched. Input: | field | type | rules | |---|---|---| | `name` | string | `required,max=64` | Output fields: - `name` (string) ## repo.update `POST /api/v1/repos/update` — command, admin Set a repository's settings: description and visibility. Fields are applied whole. private=true blanks the nobody and anonymous category strings (RFC 0004 §Private); false returns them to the fleet default. Input: | field | type | rules | |---|---|---| | `name` | string | `required,max=64` | | `description` | string | `max=300` | | `private` | boolean | — | | `homepage` | string | `max=300` | | `topics` | string | `max=600` | Output fields: - `name` (string) - `description` (string) - `private` (boolean) - `homepage` (string) - `topics` (string) ## search.all `GET /api/v1/search` — query, anonymous Full-text search across every repository the caller may read. Input: | field | type | rules | |---|---|---| | `q` | string | `required,max=200` | | `kind` | string | `oneof=checkin\|wiki\|ticket\|forum\|technote\|doc\|file` | | `repo` | string | `max=64` | | `limit` | integer | `min=0,max=200,default=50` | Output fields: - `results` (array of object {repo: string, SearchResult: object {kind: string, ref: string, label: string, snippet: string, date: string, user: string, branch: string, status: string, hash: string}}) - `count` (integer) - `searched` (integer) - `by_repo` (array of object {repo: string, count: integer}) ## search.query `GET /api/v1/r/{repo}/search` — query, anonymous Full-text search over a repository's check-ins, wiki, and tickets. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `q` | string | `required,max=200` | | `kind` | string | `oneof=checkin\|wiki\|ticket\|forum\|technote\|doc\|file` | | `limit` | integer | `min=0,max=200,default=50` | Output fields: - `results` (array of object {kind: string, ref: string, label: string, snippet: string, date: string, user: string, branch: string, status: string, hash: string}) - `count` (integer) ## settings.list `GET /api/v1/r/{repo}/settings/fossil` — query, admin List the fossil settings in force for a repository's store (RFC 0008 rung 8). On a store with no working tree the reply is supported=false with a note, until zit ships settings -R on bare stores (zit#153). Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | Output fields: - `supported` (boolean) - `note` (string) - `settings` (array of object {name: string, value: string, versionable: boolean}) ## settings.set `POST /api/v1/r/{repo}/settings/fossil` — command, admin Set one repository-tier fossil setting on a store, then return the refreshed list (RFC 0008 rung 8). supported=false until zit#153. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `name` | string | `required,max=64` | | `value` | string | `max=4096` | Output fields: - `supported` (boolean) - `note` (string) - `settings` (array of object {name: string, value: string, versionable: boolean}) ## tag.list `GET /api/v1/r/{repo}/tag` — query, anonymous List release tags — symbolic names that are not branches. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `limit` | integer | `min=0,max=500,default=100` | Output fields: - `tags` (array of object {name: string, tip: string, date: string}) - `count` (integer) ## technote.add `POST /api/v1/r/{repo}/technote` — command, token Record a technote; passing an existing event id records an edit. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `body` | string | `required,max=1048576` | | `mimetype` | string | `max=64` | | `comment` | string | `max=200` | | `event` | string | `max=64` | | `time` | string | `max=32` | Output fields: - `event` (string) - `hash` (string) ## technote.get `GET /api/v1/r/{repo}/technote/{event}` — query, anonymous Fetch one technote, rendered, by event-id prefix; rev selects one edit. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `event` | string | `required,max=64` | | `rev` | string | `max=64` | Output fields: - `event` (string) - `hash` (string) - `date` (string) - `edited` (string) - `user` (string) - `comment` (string) - `body` (string) - `html` (string) - `revisions` (integer) - `historical` (boolean) ## technote.history `GET /api/v1/r/{repo}/technote/{event}/history` — query, anonymous List every recorded edit of one technote, newest first. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `event` | string | `required,max=64` | Output fields: - `event` (string) - `comment` (string) - `edits` (array of object {hash: string, date: string, edited: string, user: string, comment: string}) - `count` (integer) ## technote.list `GET /api/v1/r/{repo}/technote` — query, anonymous List a repository's technotes at their latest edit, newest first. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | Output fields: - `notes` (array of object {hash: string, event: string, date: string, user: string, mimetype: string, comment: string, body: string, excerpt: string, revisions: integer}) - `count` (integer) ## ticket.across `GET /api/v1/me/tickets` — query, token Every tracker the caller can reach, as one listing: the same report axes as ticket.list asked of all granted repositories at once, with repository as one more browse axis. Input: | field | type | rules | |---|---|---| | `limit` | integer | `min=0,max=200,default=50` | | `state` | string | `oneof=open\|closed\|all` | | `repo` | string | `max=64` | | `type` | string | `max=64` | | `severity` | string | `max=64` | | `priority` | string | `max=64` | | `subsystem` | string | `max=64` | | `status` | string | `max=64` | | `author` | string | `max=64` | | `title` | string | `max=128` | | `order` | string | `max=32` | | `awaiting` | boolean | — | Output fields: - `tickets` (array of object {repo: string}) - `count` (integer) - `open` (integer) - `closed` (integer) - `repos` (array of object {value: string, open: integer}) - `subsystems` (array of object {value: string, open: integer}) - `authors` (array of object {value: string, open: integer}) - `truncated` (boolean) ## ticket.config `GET /api/v1/r/{repo}/ticket-config` — query, anonymous The repository's ticket vocabulary: .quarry/tickets.json at the tip of trunk, merged over fossil's defaults. List order is sort order. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | Output fields: - `vocab` (array of object {field: string, words: array of string}) - `source` (string) - `problem` (string) ## ticket.discard `POST /api/v1/r/{repo}/ticket/{id}/discard` — command, token Delete a local ticket outright — the ability the artifact log can never offer, and the whole answer to tracker spam. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `id` | string | `required,min=4,max=40` | Output fields: - `ok` (boolean) ## ticket.get `GET /api/v1/r/{repo}/ticket/{id}` — query, anonymous Fetch one ticket: folded state plus change history. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `id` | string | `required,min=4,max=40` | Output fields: - `ticket` (object {id: string, created: string, updated: string, fields: array of object {name: string, value: string}, description: string, descriptionMimetype: string, comments: array of object {hash: string, date: string, login: string, username: string, mimetype: string, body: string}, changes: array of object {hash: string, date: string, user: string, fields: array of object {name: string, value: string}}}) - `descriptionHtml` (string) - `comments` (array of object {date: string, login: string, username: string, html: string}) - `attachments` (array of object {hash: string, name: string, src: string, date: string, user: string}) - `mentions` (array of object {root: string, title: string, kind: string, state: string, branch: string, target: string, updated: string}) - `chatRefs` (object {count: integer, seq: integer, at: string}) - `local` (boolean) - `promotedTo` (string) ## ticket.intake `POST /api/v1/r/{repo}/ticket/intake` — command, anonymous File a local ticket (docs/local-tickets.md): stored on this forge, promotable into the artifact log by an admin, deletable until then. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `title` | string | `required,max=200` | | `status` | string | `max=40` | | `comment` | string | `max=65536` | | `type` | string | `max=40` | | `severity` | string | `max=40` | | `priority` | string | `max=40` | | `subsystem` | string | `max=80` | | `foundin` | string | `max=80` | Output fields: - `id` (string) ## ticket.list `GET /api/v1/r/{repo}/ticket` — query, anonymous List a repository's tickets with their folded current state. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `limit` | integer | `min=0,max=200,default=50` | | `before` | string | `max=96` | | `state` | string | `oneof=open\|closed\|all` | | `type` | string | `max=64` | | `severity` | string | `max=64` | | `priority` | string | `max=64` | | `subsystem` | string | `max=64` | | `status` | string | `max=64` | | `author` | string | `max=64` | | `title` | string | `max=128` | | `offset` | integer | `min=0,max=100000` | | `order` | string | `max=32` | | `origin` | string | `oneof=local\|fossil` | Output fields: - `tickets` (array of object {id: string, title: string, status: string, updated: string, created: string, type: string, severity: string, priority: string, subsystem: string, resolution: string, author: string, lastUser: string, comments: integer, refs: integer, local: boolean}) - `count` (integer) - `open` (integer) - `closed` (integer) - `subsystems` (array of object {value: string, open: integer}) - `authors` (array of object {value: string, open: integer}) - `next` (string) ## ticket.new `POST /api/v1/r/{repo}/ticket` — command, token Open a new ticket. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `title` | string | `required,max=200` | | `status` | string | `max=40` | | `comment` | string | `max=65536` | | `type` | string | `max=40` | | `severity` | string | `max=40` | | `priority` | string | `max=40` | | `subsystem` | string | `max=80` | | `foundin` | string | `max=80` | Output fields: - `id` (string) - `hash` (string) ## ticket.promote `POST /api/v1/r/{repo}/ticket/{id}/promote` — command, token Promote a local ticket into the artifact log: one ticket artifact with the folded state and provenance, one more collating any discussion. The local id becomes a redirect. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `id` | string | `required,min=4,max=40` | Output fields: - `id` (string) - `hash` (string) ## ticket.set `POST /api/v1/r/{repo}/ticket/{id}` — command, token Record a ticket change; empty fields are left untouched. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `id` | string | `required,min=4,max=40` | | `title` | string | `max=200` | | `status` | string | `max=40` | | `resolution` | string | `max=40` | | `comment` | string | `max=65536` | | `description` | string | `max=65536` | | `type` | string | `max=40` | | `severity` | string | `max=40` | | `priority` | string | `max=40` | | `subsystem` | string | `max=80` | | `foundin` | string | `max=80` | Output fields: - `hash` (string) ## timeline.list `GET /api/v1/r/{repo}/timeline` — query, anonymous List a repository's events — check-ins, wiki edits, ticket changes — newest first, paged by `before`. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `limit` | integer | `min=0,max=200,default=50` | | `before` | string | `max=96` | | `branch` | string | `max=64` | | `tag` | string | `max=64` | | `user` | string | `max=64` | | `y` | string | `oneof=all\|ci\|w\|t\|e\|f\|l` | Output fields: - `entries` (array of object {kind: string, hash: string, ref: string, date: string, user: string, comment: string, branch: string, isLeaf: boolean, isMerge: boolean, parents: array of string, ci: string, commentOrig: string, hidden: boolean, closed: boolean, landing: string, landingTitle: string, landingApprover: string, excerpt: string}) - `defaultBranch` (string) - `count` (integer) - `next` (string) - `indexBehind` (boolean) ## tree.list `GET /api/v1/r/{repo}/tree/{version}/{path...}` — query, anonymous List one directory of a check-in, with the directory's README rendered. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `version` | string | `max=100` | | `path` | string | `max=1024` | Output fields: - `version` (string) - `ref` (string) - `path` (string) - `entries` (array of object {name: string, path: string, dir: boolean, blob: string, files: integer, size: integer, exec: boolean, link: boolean, binary: boolean, lastHash: string, lastDate: string, lastComment: string}) - `readme` (string) - `readmeIn` (string) ## wiki.get `GET /api/v1/r/{repo}/wiki/{name}` — query, anonymous Fetch one wiki page, rendered — latest, or the revision named by rev. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `name` | string | `required,max=100` | | `rev` | string | `max=64` | Output fields: - `hash` (string) - `title` (string) - `date` (string) - `user` (string) - `mimetype` (string) - `source` (string) - `html` (string) - `outline` (array of object {level: integer, id: string, text: string}) - `deleted` (boolean) ## wiki.history `GET /api/v1/r/{repo}/wiki/{name}/history` — query, anonymous List every recorded edit of one wiki page, newest first. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `name` | string | `required,max=100` | Output fields: - `title` (string) - `edits` (array of object {hash: string, date: string, user: string}) - `count` (integer) ## wiki.list `GET /api/v1/r/{repo}/wiki` — query, anonymous List a repository's wiki pages with their latest edit. Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | Output fields: - `pages` (array of object {title: string, date: string, user: string, revisions: integer}) - `count` (integer) - `orphans` (array of string) - `wanted` (array of object {title: string, links: integer, from: array of string}) - `home` (string) ## wiki.save `POST /api/v1/r/{repo}/wiki/{name}` — command, token Record a wiki page edit (creates the page on first save). Input: | field | type | rules | |---|---|---| | `repo` | string | `required,max=64` | | `name` | string | `required,max=100` | | `body` | string | `required,max=1048576` | | `mimetype` | string | `max=64` | Output fields: - `hash` (string)