Query the Registry
The registry is a public, read-optimized knowledge base. Reads need no auth. Query it three ways: from an agent over MCP, from code over REST, or from the web UI.
From an agent (MCP)
The MCP server is the recommended path. Its answer_pack tool returns graded, license-checked citations for a question — each with a fail-closed reuse_ok and the packet_id to pull. search_registry_semantic and search_registry_hybrid expose raw retrieval.
uks serve # registry-connected by default — paste the printed config into ClaudeFrom code (REST)
All endpoints are under /api/registry. Reads are public.
Search & answer
| Endpoint | Purpose |
|---|---|
GET /api/registry/search | Keyword / full-text search |
GET /api/registry/search/semantic | Embedding-based semantic search |
GET /api/registry/search/hybrid | Hybrid (semantic + FTS, fused with RRF) |
GET /api/registry/answer?q=…&hops=1|2 | Graph-aware answer — returns a citation_chain (entity → relation → entity → sources) with per-edge license, grade, and freshness; degrades to flat retrieval when the graph is sparse |
GET /api/registry/sources | Faceted source listing with license + freshness |
Packets
| Endpoint | Purpose |
|---|---|
GET /api/registry/packets | List packets (?conformance_level=, ?verified=true, ?signer=, ?cursor= keyset pagination) |
GET /api/registry/packets/:id | Fetch a packet (raw, JSON-LD via content negotiation) |
GET /api/registry/packets/by-cid/:cid | Fetch by content address (current or historical) |
GET /api/registry/packets/:id/versions | List a packet's version history |
GET /api/registry/packets/:id/versions/:version | Fetch one historical version snapshot (full packet body) |
GET /api/registry/packets/:id/analytics | Download analytics for one packet (?days=) |
GET /api/registry/packets/:id/badge.svg | Embeddable "verified knowledge" SVG badge |
GET /api/registry/packets/:id/croissant | MLCommons Croissant export |
GET /api/registry/claims.jsonld | schema.org ClaimReview feed |
GET /api/registry/sources/by-doi?doi= | Every packet + source mentioning a given DOI |
GET /api/registry/analytics | Registry-wide download analytics + top-N packets (?days=, ?top=) |
GET /api/registry/packets/:id/versions and /versions/:version
Every publish creates an immutable version snapshot. /versions lists them newest first ({ packet_id, total, versions: [{ version, sourceCount, conformanceLevel, schemaVersion, publishedAt }] }); /versions/:version returns that exact historical packet body (subject to the same serve-time veto as a live packet — a version snapshot is the full executable content, so it's vetted the same way).
GET /api/registry/packets/:id/analytics
Per-packet download counts: { packet_id, downloads, live_downloads, version, published_at, updated_at, window_days, by_day }. downloads is the durable database total; live_downloads is a Redis counter that only tracks pulls since the counter went live (a useful cross-check). by_day is a ?days=-bounded time series (answered entirely from Redis).
GET /api/registry/packets/:id/badge.svg
A cacheable SVG suitable for <img>-embedding on an external site (e.g. "UKS L2 | verified · 12 sources"). Public packets are cached max-age=300; a request carrying viewer credentials (so it could reveal a private packet's badge) is never shared-cached.
GET /api/registry/sources/by-doi
Cross-packet DOI lookup — ?doi= is required. Returns every packet and source record across the visible, non-vetoed corpus that cites that DOI: { doi, total, limit, offset, packets: [packetId, …], sources: [...] }.
Knowledge graph
| Endpoint | Purpose |
|---|---|
GET /api/registry/entities · /entities/:name | Entities |
GET /api/registry/entities/:name/relations | Typed relationships for an entity |
GET /api/registry/entities/:name/authority | Global authority score (PageRank) + rank |
GET /api/registry/canonical/:name | Canonical (resolved) entity + aliases |
GET /api/registry/canonical/:name/suggestions | Admin: trigram-similar merge candidates |
GET /api/registry/consensus/:name | Grade-weighted consensus / contested signal |
GET /api/registry/coverage | Coverage map — domain × grade × clinical status |
GET /api/registry/stats | Registry statistics |
Canonical entity administration
Entity resolution (merging near-duplicate names like "CoQ10" / "Coenzyme Q10" into one canonical node) is admin-managed and reversible:
| Endpoint | Auth | Purpose |
|---|---|---|
GET /api/registry/canonical/:name/suggestions | admin | Trigram-similar canonical entities — merge candidates, never auto-applied |
POST /api/registry/canonical/merge | admin | Merge one canonical entity into another |
POST /api/registry/canonical/:id/split | admin | Reverse a merge — split an alias back into its own node |
POST /canonical/merge — body { "from": "name", "into": "name" }. Both names are resolved against existing canonical entities or their aliases; from is folded into into as a new alias, every occurrence is re-pointed, and the merge is recorded ({ merged: true, canonical_id, into, from }).
POST /canonical/:id/split — body { "alias": "name" }. Reverses a merge: the named alias is pulled back out of the canonical entity at :id into its own fresh canonical node, and every occurrence matching that alias is re-pointed ({ split: true, from_canonical_id, canonical: { id, name_lower } }).
Both actions are logged in RegistryEntityResolution with the acting admin's key.
Audit log & signer administration
| Endpoint | Auth | Purpose |
|---|---|---|
GET /api/registry/audit | admin | The full hash-chained audit log, with end-to-end chain verification |
POST /api/registry/admin/signers/revoke | admin | Revoke a publisher's did:key — the serve veto then drops all of that signer's content |
POST /api/registry/admin/signers/unrevoke | admin | Reverse a revocation |
GET /api/registry/admin/signers/revoked | admin | List currently revoked signer DIDs |
GET /api/registry/audit (optional ?packetId= filter) returns { total, chain_length, verified, head, entries } — verified is false (with broken_at + reason) if the hash chain doesn't verify, meaning every entry links to the previous one by hash and a slice can't be checked in isolation from the full chain.
Signer revocation is the enforcement mechanism behind the revoked signer row in the serve-time safety veto table — revoking a did:key immediately excludes all of that signer's packets/sources from every veto-scoped read path, even previously-cached ones, until unrevoked.
Example
curl "https://sabertools-production.up.railway.app/api/registry/answer?q=does%20CoQ10%20help%20statin%20myalgia&hops=2"The include_flagged query parameter
| Param | Applies to | Default | Effect |
|---|---|---|---|
?include_flagged=true (alias ?include_retracted=true) | /search, /search/semantic, /search/hybrid, /answer, /sources, /sources/by-doi, /claims.jsonld, /packets/:id, /packets/by-cid/:cid, /packets/:id/versions/:version, /packets/:id/croissant, /coverage | false | Opts back into knowledge the serve-time safety veto withholds by default — retracted sources, taken-down packets, injection-flagged content, dead links with no archive, and content from a revoked signer. Intended for human inspection of why something was withheld, not for routine consumption. |
Every result is visibility-scoped (private knowledge is excluded for non-owners). On the search, answer, sources, by-DOI, claims and raw-pull paths results are additionally safety-vetoed — retracted, taken-down, injection-flagged, dead-link, and revoked-signer knowledge is excluded by default (opt back in with ?include_flagged=true, above). Every vetoed response carries a corpus_safety attestation listing what was excluded. The knowledge-graph endpoints (/entities, /entities/:name/relations, /canonical, /consensus, /coverage) are currently visibility-scoped only — the safety veto on those paths is being extended. See Trust & safety.
From the web
Browse, search, and inspect packets — including the coverage heat-map — in the registry browser at saber.tools.
→ Related: MCP Server · Trust & safety · SDK registry client