omarchy-pool
v0.0.186
Sign in

API

Everything this site shows comes from a small JSON API at https://pkgs.omarchy-pool.org/api/v1. Reads need no authentication and allow cross-origin requests; writes need the per-job token a worker gets when it claims a task — there is no shared secret — or, on the factory's own routes, a maintainer's token.

Read

EndpointWhat it returns
GET /versionThe running release, its commit and when it was deployed.
GET /signing-keyThe pool's public signing key (fingerprint, user id, armored) — what pacman-key --add imports.
GET /statusService check, measured now: index (D1) and pool (R2) reachable, with timings. 503 when one is not. What online in the header means.
GET /statsEverything the overview shows in one response: rings, coverage (a source's row says late when its last sync is older than the pool's one threshold, 9 hours), pool totals, chart series, the latest metrics snapshot, recent journal entries, OPR recipes by origin per ring (provenance), any packages stored once per architecture and what that costs (any). Cached 60 s.
GET /pacman.conf?ring=&arch=&with=The pacman.d include for a ring and an architecture — one section per database the ring serves right now, in the include's order; with= names the optional sources to keep. What the setup script writes, and what Get started shows.
GET /releases/:ring?fields=summary&arch=The ring's current release and a light row per package (name, version, arch, filename, sha256, sizes, description). This is what omarchy-cli status reads.
GET /releases/:ring?arch=&limit=&after=&release_id=Full manifests, paged (≤ 1000 per request; above 2000 packages paging is required): page.next names the row the next page starts after — pass it as after= (keyset; offset= still works). Add include=files for file lists. release_id pins a release across pages.
GET /releases/:ring/historyThe ring's releases, newest first, with lineage (parent, from) and which one is the head.
GET /releases/:ring/diff?from=&to=&arch=What changed between two releases of the ring: packages added, removed and upgraded (same source, name and architecture, another object; another source taking a name over is its add and the other's removal). to defaults to the head, from to its parent; 410 once GC pruned a side's package list. The dashboard's /diff page and pkg-repo diff read this.
GET /packages/:sha256 · GET /packages/:sha256/provenanceOne package object's manifest; its seal — where the object came from and the proof: the upstream and its keyring for an imported one, the chain (builder, audit, approval) and the signed attestation for one the pool built.
GET /search?q=&ring=&arch=&limit=Packages in the ring whose name or description matches (exact and prefix matches first).
GET /package/:name?ring=&arch= · GET /package/:name/files?ring=&arch=Everything the package page shows: the version in every ring (ring is the one asked, the lab included; shown_ring the one the object comes from — the same, else the most stable that serves it), the manifest, declared dependencies and loaded sonames resolved to their providers, what depends on it (declared or by loading one of its libraries); the file list separately. For an OPR package, provenance: whether its recipe is Omarchy's own or AUR-synced, the AUR commit tracked, the last commit that touched it (omacom/omarchy-pkgs, read daily).
GET /graph?ring=&arch=&targets=a,bDependency closure of the targets within the ring's release: the manifests omarchy-cli check evaluates.
GET /security/componentsWhat the rings' packages embed — Go modules and crates.io crates from the binaries' build information — with the sha256 of every served object that embeds each; what the security job asks OSV about.
GET /security?ring=&arch=Packages in the ring with an open advisory: severity, confidence (exact / name-version / name-only), CVEs, exploited-in-the-wild and EPSS, rings already serving a clean version, how many packages it exposes. GET /package/:name carries the same per package plus what it is exposed through.
GET /events?kind=&limit=The journal, one line per sync, gate, promote, fast-track, health, trial, abi, security, render, publish, verify, rollback, relayout, gc, deploy, cost, audience, provenance, dispatch, job, build, enqueue, request, review, approve, withdraw, trust, role, block, category, bump, worker, leak; kind= filters to one. The metrics snapshot rides the same table and is a number, not a line.
GET /pool/unreferenced?keep=3What retention would delete now.
GET /costThe month's estimated bill, line by line (D1, R2, Workers), the projection and the guard's state. Estimated every three hours; the lines: warn at US$ 25, pause at US$ 40, cap US$ 50.

The factory (read)

What the factory's pages — Factory, Pipeline, Workers, People, Review, a person's — show. Public, cached briefly.

EndpointWhat it returns
GET /factory?limit=Workers the pool has heard from (owner, trust, mode, the agent each reported, current task), the queue (every kind: builds, pool jobs, audits), package requests, counts.
GET /factory/packages · GET /factory/built · GET /factory/tasks/:idThe registry of packages people brought (a row says landed once a maintainer approved it or the project published it); what the factory built; one task with its log tail, its approval carrying standing.
GET /factory/packages/:name/storyThe factory's view of one package: its registration and the request as the form checks it, every chain with its score, the class it has today, the rings it is in. What the package page and a person's rows draw.
GET /factory/reviewStaged community builds waiting for a maintainer, each with links to its evidence (PKGBUILD, log, .PKGINFO, the audit), the second agent's verdict (ok / warn / block, or queued / failed) and can: what you may do on the row — approve, reject, build, withdraw — and, where not, why; standing says an approval stands on the row's chain; waiting and oldest_ms count the rows a maintainer's time is asked for and the age of the oldest — the one number every tile reads. Not cached: the answer is yours.
GET /factory/tasks/:id/canThe same can for one task: {approve, reject, build, withdraw, why} for whoever asks — every page draws every button and greys the ones you may not press with this reason. Not cached.
GET /factory/tasks/:id/artifacts · GET /factory/tasks/:id/artifacts/<file>What a task has in staging (key, size, when), then a staged build's evidence: PKGBUILD, build.log, PKGINFO, audit.md, audit.json are public; the package itself is for maintainers.
GET /factory/approvals · GET /factory/maintainers · GET /factory/trust · GET /factory/blocksThe record: every decision with who signed it and whether it stands (standing: approved, not withdrawn); the maintainers (from factory/MAINTAINERS.toml, with since when); project-trusted workers; what is blocked now and why.
GET /users/:loginA contributor's or maintainer's public profile: packages, builds, approvals, workers, and the track record (Governance).
GET /users/:login/canWhat you may do on that page: {request, register, token, build, dequeue, remove, revoke, withdraw, own_only, share_worker, why, packages, workers} — the page draws every control for everyone and greys the ones you may not press with the reason in why; packages answers Remove per registration, workers Revoke and the mode per worker (a revoked one, a project's). Not cached: the answer is yours.
GET /factory/workers/selfWith a worker token: what that registration is (id, arch, trust, owner, mode) — how the image decides its mode.
GET /factory/workers/:id/logThe worker's own log — the lines between tasks, as it sent them with its claims — for its owner and the maintainers.
GET /factory/meWith a contributor token or the browser session: who you are, your packages, tasks, workers and staging quota.

Examples

Which version of a package does each ring serve?

for ring in edge rc stable; do
  curl -s "https://pkgs.omarchy-pool.org/api/v1/releases/$ring?fields=summary&arch=x86_64" \
    | jq -r --arg r "$ring" '.packages[] | select(.name == "openssl") | "\($r)\t\(.version)"'
done

What changed in stable today?

curl -s https://pkgs.omarchy-pool.org/api/v1/events?kind=promote | jq '.events[0]'
curl -s https://pkgs.omarchy-pool.org/api/v1/releases/stable/history | jq '.releases[0:3]'

Is the pool healthy right now?

curl -s https://pkgs.omarchy-pool.org/api/v1/stats \
  | jq '[.latest[] | select(.kind == "health") | {ring, arch: .source, status, at: .created_at}]'

The static side (what pacman reads)

curl -sI https://pool.omarchy-pool.org/core/x86_64/omarchy-core-stable.db | head -3
curl -s  https://pool.omarchy-pool.org/core/x86_64/omarchy-core-stable.db | tar -tz | head

Write (jobs only)

Bearer omj.…: the per-job token issued at POST /factory/claim, scoped to what that task needs (pool:write, release:<ring>, artifacts:*:<ring>, security:write, gc, events) and valid for its lease. Used by pkg-repo work; documented in the security model. A maintainer queues one of these jobs by hand with POST /factory/jobs.

EndpointWhat it does
POST /factory/claim · POST /factory/tasks/:id/heartbeat · POST /factory/tasks/:id/complete · POST /factory/tasks/:id/failThe worker's protocol: claim the next task of its role and architecture (a lease and the per-job token come back), keep the lease alive, hand the result in, or say why not.
PUT /pool/:sha256?filename=&arch= · PUT /pool/:sha256/sig?filename=&arch= · POST /pool/:sha256/multipart?filename=&arch= · PUT /pool/multipart/:upload/part/:n?key= · POST /pool/multipart/:upload/complete?key=Store a package object (integrity-checked, never overwritten) and its upstream signature; a large archive in parts.
POST /pool/:sha256/sign?filename=&arch=The pool signs a package it built (source factory) with its own key; the key never leaves the service.
POST /packages?source=&arch= · POST /packages/knownIndex a manifest; ask which sha256s are already indexed.
POST /releasesCreate, promote or roll back a release (an index write). An added package replaces its own source's build of that name; another source's stays (the include's order decides between them). remove drops a name from every source, remove_from ({source, name}) from one; arch moves one architecture only while the other keeps what the ring serves. The lab (ring=lab) takes any object and is never promoted from or into.
PUT /releases/:id/artifacts/:kind?repo=&arch=Publish a rendered database beside the packages (db, db.sig, files, files.sig); the pool signs it as it stores it.
PUT /security/advisories · PUT /security/matches · POST /security/prune?before=The security job's writes: the advisories it read from the feeds, what they match in the rings, and the prune of what is older than a date.
POST /events · POST /pool/gc · POST /pool/relayoutRecord a journal entry — the project's jobs and maintainers only, a community build's token carries no events scope, and a run link must be https, a release an id; run retention; one step of the one-time move to one directory per source (the relayout job).
POST /factory/enqueue · POST /factory/tasks/:id/cancelThe enqueue job's writes (a maintainer by hand too): queue the project's build of a package for its architectures, cancel a task.
PUT /factory/tasks/:id/artifacts/<file> · POST /factory/tasks/:id/artifacts/<file>/multipartA community build's token uploads its evidence to its own staging workspace, a large file in parts; an audit's token adds audit.json / audit.md to a staged build, and nothing else.

Write (people)

Bearer omc_… (a contributor token from your profile) or the browser session after Sign in with GitHub. Nothing here touches the pool directly: maintainers queue jobs and approve builds; workers do the work with per-job tokens.

EndpointWhoWhat it does
POST /factory/register · POST /factory/tokencontributorA GitHub token, used once to read your login and never stored, answers a contributor token (omc_…); signed in on the dashboard, mint or replace the same token from your page.
POST /factory/packages · POST /factory/packages/:name/build · DELETE /factory/packages/:name/builds/:id · DELETE /factory/packages/:name · DELETE /factory/tasks/:id/artifactscontributorRequest a package (the project's URL, a description, the licence, the checklist — written once to the record), ask for a build, take a queued build out, remove the request, or drop a finished task's staging objects (the 5 GB quota; the pool reclaims superseded, rejected and published builds itself).
POST /factory/workers · DELETE /factory/workers/:id · POST /factory/workers/:id/mode · POST /factory/workers/self/modecontributorRegister a worker (the token is shown once), revoke it, set whether it builds everyone's queue or its owner's packages only — from the page, or the worker itself through its token (omarchy-worker share on|off).
POST /factory/tasks/:id/build · POST /factory/tasks/:id/approve · POST /factory/tasks/:id/reject · POST /factory/tasks/:id/withdrawmaintainerHave the project build a contributor's staged package again (its agent, a trusted worker, its own recipe); approve the project's build into edge — the decision on the record, a publish job; send either back with a note; or take a standing approval back, the reason on the record. Never your own package — a withdrawal excepted: undoing is not deciding. A refusal answers the reason can gives.
POST /factory/packages/:name/categorymaintainerSettle the package's category (one of the list) — at review or any time after; a category line in the journal says who and from what.
POST /factory/jobsmaintainerQueue a pool job by hand (sync, promote, rollback, render, health, security, enqueue, gc, verify, relayout, trial) — what pkg-repo job calls.
POST /factory/workers/:id/trustmaintainerProject trust on two maintainers' word: the first call proposes (202), a second maintainer's — never the same person's; the owner's counts as the second word, never the first — confirms; {"trust":"community"} takes it back at one word. Each step an event; the trust a signed record under workers/<id>/.
POST /factory/record/withdrawmaintainer{key, reason} — a record taken off the public bucket (a log that carried what it should not have); its signature and staging copy go with it, and a signed <key>.tombstone.json says who, why and what was there.
POST /factory/contributors/:login/block · POST /factory/contributors/:login/unblock · POST /factory/packages/:name/block · POST /factory/packages/:name/unblockmaintainerThe brake, with a reason on the record: a blocked contributor gets nothing more in (workers revoked, tasks cancelled, packages out of the rings, their projects closed to new accounts); a blocked package leaves every ring. Lifting is by another maintainer.
GET /auth/github · GET /auth/me · GET /auth/logoutanyoneSign in with GitHub (a session cookie for the dashboard); who is signed in; sign out — the session stops working on the server, the CLI token is untouched.