Registry contract
Base addresses, discovery, paged catalogs and immutable release downloads.
Connect a registry base address, such as plugins.hay.so or https://plugins.example.com/team/. Hay adds HTTPS to a bare hostname and preserves nested path prefixes. The trusted host discovers catalog endpoints and downloads artifact bytes; plugin frames do neither.
Discovery
Hay requests <base>/.well-known/hay-registry.json:
{
"schemaVersion": "hay.registry.discovery/1",
"name": "Team tools",
"catalog": "v1/registry/plugins",
"release": "v1/registry/releases/{id}/{version}"
}name is nonempty and up to 100 characters. catalog is required; release is optional. The release template must contain exactly one {id} and one {version}; Hay URL-encodes each value before substituting it.
Paths resolve against the registry base, including catalog, release, pagination next and artifact paths. For a base of https://plugins.example.com/team/, artifacts/file.hay-plugin.json resolves under /team/, not relative to a catalog page. Keep paths relative to preserve a nested prefix. Absolute URLs and protocol-relative origins are refused; every resolved URL must remain on the registry origin.
Only a discovery response of HTTP 404 or 410 falls back to <base>/index.json. Invalid discovery JSON, redirects and other failures are errors, not a reason to bypass discovery.
Paged catalog
A dynamic catalog returns:
{
"schemaVersion": "hay.registry.page/1",
"plugins": [{
"manifest": {"...": "complete hay.app/1 manifest"},
"bundle": {
"path": "artifacts/<sha256>.hay-plugin.json",
"sha256": "<64 lower-case hexadecimal characters>",
"size": 1234
}
}],
"next": "v1/registry/plugins?after=<opaque-cursor>"
}This illustrates the shape; supply a complete manifest, real digest and exact size. Omit next on the final page. Each ID/version pair must be unique across the catalog. A page has at most 100 entries and 1,000,000 bytes. Hay’s hosted service currently returns up to 50 entries per page, within the byte limit.
The current client assembles pages automatically, with limits of 5,000 releases, 100 pages, 20,000,000 cumulative catalog bytes and a 30-second overall operation deadline. Cycles, duplicate releases and exceeded bounds fail explicitly. This is bounded browsing, not an unlimited catalog client.
Direct release lookup
When discovery supplies release, installation looks up the exact ID/version without walking catalog pages:
{
"schemaVersion": "hay.registry.release/1",
"manifest": {"...": "complete hay.app/1 manifest"},
"bundle": {
"path": "artifacts/<sha256>.hay-plugin.json",
"sha256": "<64 lower-case hexadecimal characters>",
"size": 1234
}
}The returned manifest must match the requested ID and version. Without a direct endpoint, Hay finds the release through the bounded catalog read. Direct lookup does not bypass integrity checks, installation review or capability grants.
Static compatibility
Static tooling exports a discovery file whose catalog is index.json; no release endpoint is required. That catalog keeps the original format:
{
"schemaVersion": "hay.registry/1",
"name": "Team tools",
"plugins": [{
"manifest": {"...": "complete hay.app/1 manifest"},
"bundle": {
"path": "artifacts/<sha256>.hay-plugin.json",
"sha256": "<64 lower-case hexadecimal characters>",
"size": 1234
}
}]
}A legacy index is limited to 100 entries and 1,000,000 bytes. Hosted publishing is not capped at 100 releases: the service uses paged catalogs and direct lookup. Its legacy index returns an explicit upgrade error once it exceeds the compatibility bounds, rather than silently omitting older releases.
Artifact integrity and transport
sha256 hashes the exact downloaded artifact bytes, including whitespace and trailing newlines. size is the exact byte count, from 1 to 2,000,000. The artifact is a complete hay.bundle/1 bundle; its manifest must exactly equal the release metadata. A digest from another serialization fails verification.
Public registries require HTTPS. Numeric loopback HTTP is allowed for local development. Plain HTTP on public hosts, embedded credentials, fragments, redirects and cross-origin paths are refused. Public and custom registry requests omit credentials. The host’s built-in personal-registry access is the narrow exception: an online-validated bearer session goes only to the current account’s exact private base, with every endpoint and artifact confined to that path. Cookies remain omitted and redirects are refused.
Each request has at most ten seconds, within the operation’s 30-second deadline. Streamed byte limits apply even without a trustworthy Content-Length. Discovery is bounded at 16,000 bytes; catalog pages and direct release metadata at 1,000,000 bytes; bundles at 2,000,000 bytes.
Source identity and trust
A registry’s base address identifies the source independently of its catalog transport. Saved /index.json addresses normalize to their parent base. Historical installation provenance remains intact; source comparisons recognize the equivalent old and new address for updates and restoration. Changing a descriptor endpoint does not create a new publisher or permit a foreign-source replacement.
Provenance records the registry source, download URL, digest, size and installation time. A plugin cannot change its provenance or grants through SDK calls. The read-only registry protocol is a host responsibility, not a window.Hay plugin API.
The format is unsigned. A digest verifies bytes against the selected registry, not legal identity or code safety. The publisher API separately authorizes publication under an account-owned namespace. Static custom registries need no Hay account service; author names there remain self-reported.
Marketplace and install links
Marketplace search returns latest public plugins for human browsing, independently of the full release catalog. Its APIs and numeric release ordering are documented in the publisher API. An exact hay://install link pins the registry base, plugin ID, version and SHA-256. It opens an overview in Hay; Review installation and inline approval remain separate. It never changes the saved registry selection or grants capabilities. See the install-link contract.
Downloadable schemas
Structural schemas are available for discovery, catalog pages, direct releases and legacy indexes. Passing a schema does not prove same-origin confinement, template validity, exact bytes or installation approval; runtime checks still apply.
Errors
Invalid JSON, unsupported fields, duplicate releases, unavailable versions, pagination cycles, oversized responses, wrong digests, manifest mismatches and redirects fail closed. Fix the registry or publish a correctly versioned release; do not bypass review or replace user records to work around an error.