ClawHub API v1 Overview and Conventions

This page describes the public REST API v1 for ClawHub, including base URL, authentication, rate limits, and guidelines for building catalogs or search interfaces. It is intended for developers who want to reuse public skill data.

Read this when

  • Building API clients
  • Adding endpoints or schemas

API v1

Base: https://clawhub.ai

OpenAPI: /api/v1/openapi.json

Public catalog reuse

ClawHub's public read APIs let you construct your own catalog, directory, or search interface. Skill metadata and files that are publicly accessible fall under ClawHub's skill license terms, and the API carries rate limits, so consumption should stay reasonable.

Guidelines:

  • For catalog listings, rely on public read endpoints like GET /api/v1/skills, GET /api/v1/search, and GET /api/v1/skills/{slug}.
  • Cache what you fetch and honor 429, Retry-After, and the rate-limit headers rather than polling frequently.
  • When you show listings, point back to the canonical ClawHub skill URL so users can check the original registry entry.
  • Canonical page URLs should follow the pattern https://clawhub.ai/<owner>/skills/<slug>.
  • Never suggest that ClawHub endorses, verifies, or runs the third-party site.
  • Do not expose hidden, private, or moderation-blocked content by working around public API filters or authentication boundaries.

Auth

  • Public read: no token needed.
  • Write and account operations: Authorization: Bearer clh_....

Rate limits

Enforcement tied to authentication:

  • Anonymous requests: limited per IP.

  • Authenticated requests (valid Bearer token): limited per user bucket.

  • A missing or invalid token reverts to IP-based limits.

  • Read: 3000/min per IP, 12000/min per key

  • Write: 300/min per IP, 3000/min per key

  • Download: 1200/min per IP, 6000/min per key

Headers: X-RateLimit-Limit, X-RateLimit-Reset, RateLimit-Limit, RateLimit-Reset; X-RateLimit-Remaining, RateLimit-Remaining, and Retry-After appear on 429.

Meaning:

  • X-RateLimit-Reset: Unix epoch seconds, the absolute reset time
  • RateLimit-Reset: seconds to wait before the limit resets
  • X-RateLimit-Remaining / RateLimit-Remaining: the precise remaining quota when included; sharded successful calls leave it out instead of providing an approximate global figure
  • Retry-After: seconds to pause before retrying on 429

Sample 429:

HTTP/2 429
x-ratelimit-limit: 20
x-ratelimit-remaining: 0
x-ratelimit-reset: 1771404540
ratelimit-limit: 20
ratelimit-remaining: 0
ratelimit-reset: 34
retry-after: 34

How clients should behave:

  • When Retry-After is available, use it first.
  • Otherwise fall back to RateLimit-Reset or calculate the wait from X-RateLimit-Reset.
  • Introduce jitter into retry attempts.

Errors

  • v1 errors come back as plain text (text/plain; charset=utf-8), covering 400, 401, 403, 404, 429, and blocked-download responses.
  • Unknown query parameters are ignored to preserve compatibility.
  • Known query parameters carrying invalid values trigger 400.

Endpoints

Public read:

  • GET /api/v1/search?q=...
    • You can optionally narrow results with highlightedOnly=true or nonSuspiciousOnly=true.
    • For deterministic matches on the exact slug, set mode to mode=exact.
    • Supplying an invalid mode value triggers 400 Invalid search mode as the response.
    • nonSuspicious=true serves as the legacy name for this endpoint.
  • GET /api/v1/skills?limit=&cursor=&sort=
    • sort accepts updated as its default, along with recommended (which maps to default), createdAt (mapped to newest), downloads, stars (corresponding to rating), and name; the older install aliases installsCurrent, installs, and installsAllTime all resolve to downloads and trending.
    • With prefix, listing is deterministic, ordered by ascending slug prefix; pick up where you left off using nextCursor.
    • An invalid sort value yields 400 in the response.
    • When sorting is anything other than trending, the cursor parameter takes effect.
    • nonSuspiciousOnly=true is available as an optional filter.
    • The legacy alias here is nonSuspicious=true.
    • If nonSuspiciousOnly=true is enabled, cursor-based pages might return fewer than limit entries; keep going with nextCursor.
    • Signals for engagement and recency drive the behavior of recommended.
  • GET /api/v1/skills/{slug}
  • GET /api/v1/skills/{slug}/moderation
  • GET /api/v1/skills/{slug}/versions?limit=&cursor=
  • GET /api/v1/skills/{slug}/versions/{version}
  • GET /api/v1/skills/{slug}/scan?version=&tag=
  • GET /api/v1/skills/{slug}/file?path=&version=&tag=
  • GET /api/v1/resolve?slug=&hash=
  • GET /api/v1/download?slug=&version=&tag=
    • For hosted skills, the ZIP bytes returned are deterministic.
    • If a GitHub-backed skill is current and has a clean or suspicious scan, the response is a JSON public-github handoff descriptor rather than ClawHub bytes.
  • GET /api/v1/skills/export?startDate=&endDate=&limit=&cursor=
    • Hosted skills get exported exactly as the stored files.
    • When a GitHub-backed skill is current and carries a clean or suspicious scan, the export takes the form of public-github handoff descriptors.
  • GET /api/v1/packages?limit=&cursor=&sort=
    • sort supports updated as the default, plus recommended and downloads, with installs as the legacy alias.
    • Passing an invalid sort value results in 400 being returned.
  • GET /api/v1/plugins?limit=&cursor=&sort=
  • sort: recommended (default), downloads, updated, legacy alias installs
  • GET /api/v1/plugins/search?q=...
  • GET /api/v1/packages/{name}/versions/{version}/artifact
  • GET /api/v1/packages/{name}/versions/{version}/security
  • GET /api/v1/packages/{name}/versions/{version}/artifact/download
  • GET /api/npm/{package}
  • GET /api/npm/{package}/-/{tarball}.tgz

Authentication is mandatory:

  • POST /api/v1/skills (publish, multipart preferred)
  • DELETE /api/v1/skills/{slug}
  • DELETE /api/v1/packages/{name}
  • POST /api/v1/skills/{slug}/undelete
  • POST /api/v1/packages/{name}/undelete
  • POST /api/v1/skills/{slug}/rename
  • POST /api/v1/skills/{slug}/merge
  • POST /api/v1/skills/{slug}/transfer
  • POST /api/v1/packages/{name}/transfer
  • POST /api/v1/skills/{slug}/transfer/accept
  • POST /api/v1/skills/{slug}/transfer/reject
  • POST /api/v1/skills/{slug}/transfer/cancel
  • GET /api/v1/skills/export?startDate=&endDate=&limit=&cursor=
  • GET /api/v1/plugins/export?startDate=&endDate=&limit=&cursor=&family=
  • GET /api/v1/transfers/incoming
  • GET /api/v1/transfers/outgoing
  • GET /api/v1/whoami

Restricted to administrators:

  • POST /api/v1/users/reserve sets aside root slugs and private no-release package placeholders for an owner handle.

Legacy

The older /api/* and /api/cli/* endpoints remain accessible. Check DEPRECATIONS.md for details.

797 words · updated Aug 1, 2026