Skip to content

Public Forge web API

The marketing explorer uses a deliberately narrow, read-only Forge surface. It is separate from the authenticated app API and may return only server-authorized, ciphertext-safe projections.

Routes

Every route is a GET below /public/v1 and answers application/json, except the one asset route noted in the table. {org}/{repo} is the published alias described below. The only query parameters the edge forwards to a projection are ref, path, base, head, state, after, and limit — every other parameter is dropped rather than passed through, so an unrecognized one can never become an unreviewed selector.

Route Projection
/repositories The published catalog, filtered live by visibility
/discovery The cross-repository aggregate the explorer's landing view uses
/repositories/{org}/{repo} Public repository identity and summary
/repositories/{org}/{repo}/snapshot Repository summary, recent changes, and proposals
/repositories/{org}/{repo}/tree?ref=&path= Public tree entries
/repositories/{org}/{repo}/blob?ref=&path= One clear file's contents
/repositories/{org}/{repo}/blame?ref=&path= Per-line attribution for a clear file
/repositories/{org}/{repo}/changes?ref= Public change summaries
/repositories/{org}/{repo}/changes/{id} One public change
/repositories/{org}/{repo}/changes/{id}/diff One change's diff
/repositories/{org}/{repo}/compare?base=&head= The file-level comparison of two refs
/repositories/{org}/{repo}/conflicts?ref= Open conflict summaries
/repositories/{org}/{repo}/conflict?ref=&path= One conflict, with its clear sides
/repositories/{org}/{repo}/lanes, /tags, /policies Lanes, tags, and the policy shapes
/repositories/{org}/{repo}/proposals?after=&limit= Public proposal summaries
/repositories/{org}/{repo}/proposals/{id} One public proposal
/repositories/{org}/{repo}/insights The repository's aggregate activity view
/repositories/{org}/{repo}/releases… Published releases (list, latest, one by id)
/repositories/{org}/{repo}/releases/{id}/assets/{name} The asset bytes — the one route that is not JSON
/repositories/{org}/{repo}/issues… Issues, one issue, and one issue's comments

The exact response types live in the shared tovio-forge-domain::public_read module; this surface does not introduce a second repository domain model. The edge derives them from verified commits, trees, refs, and proposal records.

No protected content, ever. A policy-protected path never has its plaintext rendered here under any operation: it appears as metadata with its protection marker in a tree, and is excluded from the content-bearing shapes (blob, diff, blame, conflict). The edge holds no recipient key and does not decrypt — there is no caller to unseal for. A projection also omits account, membership, organization-administration, audit, billing, authentication, private-key, recipient-key, capability-chain, and mutation data.

This surface is read-only. /public/v1 exposes no mutation of any kind — writes reach the Forge only through the authenticated app API, never from the marketing origin.

A deployment publishes nothing by default. A repository is reachable only when it has an exact alias in PUBLIC_REPOSITORY_CATALOG and its live Forge repository marker remains public.

Browser boundary

  • Allow CORS from exactly https://tovio.dev for these GET routes.
  • Allow the authenticated API from exactly https://app.tovio.dev; do not grant the marketing origin mutation methods or credentialed requests.
  • Reject redirects and non-JSON responses. Bound each response before parsing.
  • Return an explicit unavailable/error response when the Forge cannot serve the projection. The website must never substitute demonstration data that looks live.

The Astro implementation enforces HTTPS outside loopback, omits credentials, accepts only GET, and caps responses at 1 MiB. Authorization and disclosure decisions remain server responsibilities.

Last reviewed September 9, 2026

Suggest an improvement to this page Not for security reports — see disclosure