List catalog

Searches AND browses the cross-org catalog: every project, app and site the fleet has built, whichever org built it.

GET /v1/catalog

Addresshttps://api.hanzo.ai/v1/catalog
MethodGET
Operationget_catalog
AuthAuthorization: Bearer $HANZO_API_KEY

Searches AND browses the cross-org catalog: every project, app and site the fleet has built, whichever org built it.

It reads TWO corpora and returns them as one page — the published, world-readable catalog that every caller sees, plus the caller's OWN org's private entries when the request carries a validated principal. Each row says which it came from in scope, so a client can warn before sharing a link. An anonymous caller simply gets the published one; no filter can ever widen a caller into another tenant's corpus, because the query that would return it is never run for them.

A request with no q is a browse rather than a search, and both answer the same shape: the page, the total before paging, and the facet counts over the whole matching set.

Request

10 fields.

FieldInTypeRequiredDescription
qquerystring—Q is the free-text query the lexical index scores relevance on.
orgquerystring—Org narrows to one builder org: hanzo | lux | zoo.
kindquerystring—Kind narrows to repo | site.
originquerystring—Origin narrows to what a row IS to you: template | community | third-party | product.
archetypequerystring—Archetype narrows to one project archetype.
languagequerystring—Language narrows to one implementation language.
templatequerystring—Template narrows a lane to ONE lineage: the id of the parent everything returned was forked from.
forkablequerystring—Forkable is tri-state: "true" selects the forkable rows, "false" selects the rest, and anything else — including absent — applies no filter at all.
limitquerystring—Limit caps the page at 200, default 50.
offsetquerystring—Offset is where the page starts, default 0, with the same tolerance.

Response

StatusBodyMeaning
200catalog.catalogPageok
defaultproblem-detailsrefused

200 body — 24 fields.

FieldInTypeAlwaysDescription
databodycatalog.Entry[]—Data is the page of matching entries, most recently updated first.
data[].archetypebodystring—Archetype is WHAT KIND OF THING this is, from a closed and ordered list — model | contract | chain | sdk | template | infra | site | app — derived from the repository's own topics, name and description, first match winning, and always site for a deployed site.
data[].descriptionbodystring—Description is the repository's own one-line GitHub description, carried verbatim.
data[].forkablebodyboolean—Forkable is NOT omitempty: false is an answer here, not a missing field.
data[].idbodystring—ID is "<org>/<name>" and is the corpus's primary key: a re-published entry updates in place under it rather than accumulating duplicates, so it is the one handle stable enough to link to or to name in a template filter.
data[].kindbodystring—repo | site
data[].languagebodystring—Language is the repository's primary implementation language as GitHub computes it ("Go", "TypeScript"), and the case is GitHub's.
data[].licensebodystring—License is the terms that upstream work carries, in whichever form the half that credited it had: an SPDX id ("MIT", "Apache-2.0") on a GitHub fork, free text on a site whose publisher declared it.
data[].namebodystring—Name is the short identifier inside the org — the repository's name, or the site's slug — and is the half of ID after the slash.
data[].notebodystring—Note is why a row is NOT in the published catalog, set by the admission gate (gate.go) on the sites it holds back.
data[].orgbodystring—hanzo | lux | zoo
data[].originbodystring—Origin is WHAT THIS IS TO YOU: template | community | third-party | product (origin.go owns the four nouns and derives them).
data[].repobodystring—source
data[].scopebodystring—Scope is provenance, not storage: "public" for a row from the published corpus, "org" for one only this caller can see.
data[].starsbodyinteger (int64)—Stars is GitHub's stargazer count for the source repository, read at the last sync and never accumulated here.
data[].templatebodystring—lineage, if forked from one
data[].titlebodystring—Title is what to SHOW.
data[].updatedbodystring—Updated is when the thing last MOVED, as RFC 3339 in UTC: a repository's last push, or a site's last deploy.
data[].upstreambodystring—Upstream/License credit the third-party work an entry was published from: the difference between "this org built it" and "somebody else built it and we are showing it to you".
data[].urlbodystring—live, if it is deployed
facetsbodyobject—Facets counts the whole matching set along every browse axis, so a rail a client renders is a rail that has results behind it.
facets.*bodyobject—
facets.*.*bodyinteger (int64)—
totalbodyinteger (int64)—Total is how many entries matched BEFORE paging — what a pager sizes itself on.

Failure carries the platform error shape — see Errors.

Examples

hanzo catalog get
import { Configuration, CatalogApi } from 'hanzoai';

const api = new CatalogApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.getCatalog();
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import CatalogApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = CatalogApi(client).get_catalog()
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.CatalogAPI.GetCatalog(context.Background()).Execute()
if err != nil {
	return err
}
use hanzo_client::apis::{configuration::Configuration, catalog_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = catalog_api::get_catalog(&cfg, Default::default()).await?;
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.CatalogApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new CatalogApi(client).getCatalog();
curl https://api.hanzo.ai/v1/catalog \
  -H "Authorization: Bearer $HANZO_API_KEY"

MCP reaches catalog through the catalog tool, which names its 1 operations with its own verbs — this one among them, under a name only MCP declares. describe explains any of them:

curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "describe",
         "arguments": {
           "op": "list_catalogs"
         }
       }
     }'

Catalog API · All Hanzo APIs · Interactive reference

Was this page useful?