- Repo transferred hanzobot/hub → hanzoai/market (matches owned hanzo.market domain) - npm package: bothub → @hanzoai/market, packages/bothub → packages/market - bothub-schema → @hanzoai/market-schema - CLI binary: bothub → market - Brand: Bot Hub → Hanzo Market across ~95 user-facing surfaces (README, docs, k8s, Dockerfile, public/manifest.json, OG image, CLI banner, site config, theme) - Brand-neutral white-label: src/brand/ owns BrandConfig + BrandTheme + loader, public/brands/<id>.json presets for hanzo, zoo, lux, pars, liquidity, generic - BRAND_ID env at build picks default; ConfigMap-mounted brand.json overrides at runtime - Legacy paths retained for compat: ~/.bothub, .bothubignore, /.well-known/bothub.json, bothub-theme localStorage key, LEGACY_HOSTS for hub.hanzo.bot/clawhub.ai - Fixed broken sed-replace artifacts in packages/market/src/cli/botConfig.test.ts - Drops Clawd/OpenClaw dead brand surface, keeps Clawdis* schema types and clawd skill directory paths (backward compat for installed bot products)
6.1 KiB
summary, read_when
| summary | read_when | ||
|---|---|---|---|
| HTTP API reference (public + CLI endpoints + auth). |
|
HTTP API
Base URL: https://hanzo.market (default).
All v1 paths are under /api/v1/... and implemented by the API server (Hono).
Legacy /api/... and /api/cli/... remain for compatibility (see DEPRECATIONS.md).
OpenAPI: /api/v1/openapi.json.
Rate limits
Enforced per IP + per API key:
- Read: 120/min per IP, 600/min per key
- Write: 30/min per IP, 120/min per key
- Download: 20/min per IP, 120/min per key (
/api/v1/download)
Headers:
X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset,Retry-After(when limited)
IP source:
- Uses
cf-connecting-ip(Cloudflare) for client IP by default. - Set
TRUST_FORWARDED_IPS=trueto opt in tox-real-ip,x-forwarded-for, orfly-client-ip(non-Cloudflare deployments).
Public endpoints (no auth)
GET /api/v1/search
Query params:
q(required): query stringlimit(optional): integerhighlightedOnly(optional):trueto filter to highlighted skills
Response:
{ "results": [{ "score": 0.123, "slug": "gifgrep", "displayName": "GifGrep", "summary": "…", "version": "1.2.3", "updatedAt": 1730000000000 }] }
Notes:
- Results are returned in relevance order (embedding similarity + exact slug/name token boosts + popularity prior from downloads).
GET /api/v1/skills
Query params:
limit(optional): integer (1–200)cursor(optional): pagination cursor (only forsort=updated)sort(optional):updated(default),downloads,stars(alias:rating),installsCurrent(alias:installs),installsAllTime,trending
Notes:
trendingranks by installs in the last 7 days (telemetry-based).
Response:
{ "items": [{ "slug": "gifgrep", "displayName": "GifGrep", "summary": "…", "tags": { "latest": "1.2.3" }, "stats": {}, "createdAt": 0, "updatedAt": 0, "latestVersion": { "version": "1.2.3", "createdAt": 0, "changelog": "…" } }], "nextCursor": null }
GET /api/v1/skills/{slug}
Response:
{ "skill": { "slug": "gifgrep", "displayName": "GifGrep", "summary": "…", "tags": { "latest": "1.2.3" }, "stats": {}, "createdAt": 0, "updatedAt": 0 }, "latestVersion": { "version": "1.2.3", "createdAt": 0, "changelog": "…" }, "owner": { "handle": "steipete", "displayName": "Peter", "image": null } }
GET /api/v1/skills/{slug}/versions
Query params:
limit(optional): integercursor(optional): pagination cursor
GET /api/v1/skills/{slug}/versions/{version}
Returns version metadata + files list.
GET /api/v1/skills/{slug}/file
Returns raw text content.
Query params:
path(required)version(optional)tag(optional)
Notes:
- Defaults to latest version.
- File size limit: 200KB.
GET /api/v1/resolve
Used by the CLI to map a local fingerprint to a known version.
Query params:
slug(required)hash(required): 64-char hex sha256 of the bundle fingerprint
Response:
{ "slug": "gifgrep", "match": { "version": "1.2.2" }, "latestVersion": { "version": "1.2.3" } }
GET /api/v1/download
Downloads a zip of a skill version.
Query params:
slug(required)version(optional): semver stringtag(optional): tag name (e.g.latest)
Notes:
- If neither
versionnortagis provided, the latest version is used. - Soft-deleted versions return
410. - Download stats are counted as unique identities per hour (
userIdwhen API token is valid, otherwise IP).
Auth endpoints (Bearer token)
All endpoints require:
Authorization: Bearer clh_...
GET /api/v1/whoami
Validates token and returns the user handle.
POST /api/v1/skills
Publishes a new version.
- Preferred:
multipart/form-datawithpayloadJSON +files[]blobs. - JSON body with
files(storageId-based) is also accepted.
DELETE /api/v1/skills/{slug} / POST /api/v1/skills/{slug}/undelete
Soft-delete / restore a skill (moderator/admin only).
Status codes:
200: ok401: unauthorized403: forbidden404: skill/user not found500: internal server error
POST /api/v1/users/ban
Ban a user and hard-delete owned skills (moderator/admin only).
Body:
{ "handle": "user_handle", "reason": "optional ban reason" }
or
{ "userId": "users_...", "reason": "optional ban reason" }
Response:
{ "ok": true, "alreadyBanned": false, "deletedSkills": 3 }
POST /api/v1/users/role
Change a user role (admin only).
Body:
{ "handle": "user_handle", "role": "moderator" }
or
{ "userId": "users_...", "role": "admin" }
Response:
{ "ok": true, "role": "moderator" }
GET /api/v1/users
List or search users (admin only).
Query params:
q(optional): search queryquery(optional): alias forqlimit(optional): max results (default 20, max 200)
Response:
{
"items": [
{
"userId": "users_...",
"handle": "user_handle",
"displayName": "User",
"name": "User",
"role": "moderator"
}
],
"total": 1
}
POST /api/v1/stars/{slug} / DELETE /api/v1/stars/{slug}
Add/remove a star (highlights). Both endpoints are idempotent.
Responses:
{ "ok": true, "starred": true, "alreadyStarred": false }
{ "ok": true, "unstarred": true, "alreadyUnstarred": false }
Legacy CLI endpoints (deprecated)
Still supported for older CLI versions:
GET /api/cli/whoamiPOST /api/cli/upload-urlPOST /api/cli/publishPOST /api/cli/telemetry/syncPOST /api/cli/skill/deletePOST /api/cli/skill/undelete
See DEPRECATIONS.md for removal plan.
Registry discovery (/.well-known/bothub.json)
The CLI can discover registry/auth settings from the site:
/.well-known/bothub.json(JSON, preferred; legacy file name retained for older CLIs)
Schema:
{ "apiBase": "https://hanzo.market", "authBase": "https://hanzo.market", "minCliVersion": "0.0.5" }
If you self-host, serve this file (or set MARKET_REGISTRY explicitly; legacy BOTHUB_REGISTRY / CLAWDHUB_REGISTRY).