API Security Contract
June 8, 2026 ยท View on GitHub
HeyClaude exposes a public read-only registry API plus a small set of limited dynamic endpoints. Registry publishing is not exposed over the public API.
Public Read-Only Surfaces
/api/registry/manifest/api/registry/categories/api/registry/search/api/registry/feed/api/registry/diff/api/registry/entries/{category}/{slug}/api/registry/entries/{category}/{slug}/llms/api/mcp/data/*.jsonregistry artifacts/data/feeds/index.json/data/feeds/categories/{category}.json/data/feeds/platforms/{platform}.json/data/skill-adapters/...generated adapters/feed.xmland static registry changelog artifacts
Limited Dynamic Surfaces
/api/votes/query/api/votes/toggle/api/community-signals/api/community-signals/query/api/intent-events/api/newsletter/subscribe/api/newsletter/webhook/api/og/api/submissions/preflight/api/listing-leads/api/admin/listing-leads/api/admin/jobs/api/admin/jobs/health
Controls
- API route contracts live in
apps/web/src/lib/api/contracts.ts. Route files underapps/web/src/routes/api/**are thin TanStack server handlers that delegate to the central router inapps/web/src/lib/api/router.ts. - Request params, queries, and JSON bodies are validated with Zod. The generated
OpenAPI document in
cloudflare/api-schema-heyclaude-openapi.yamlis derived from those Zod contracts withpnpm generate:openapiand checked withpnpm validate:openapi. - API errors use one normalized envelope:
{ ok: false, error: { code, message, details? }, requestId? }. - Public browser-facing endpoints keep origin checks and route-level rate limits.
- JSON writes require content-type validation and payload size limits.
- Admin review endpoints require bearer or admin-token headers.
- Webhooks require provider signatures when configured.
- Newsletter template syncing is a local operator script that talks to Resend Templates only; the public site does not expose campaign-send, scheduling, or template-management endpoints.
- Website submission preflight requires origin checks, payload limits, schema validation, honeypot discard logging, and existing-content duplicate checks. It never creates GitHub issues, branches, pull requests, labels, comments, or registry content.
- Website submissions do not accept or publish package uploads. Community ZIP/MCPB artifacts are review/quarantine material only; public downloads are maintainer-built artifacts after review.
- PR creation and final review happen in the private Cloudflare submission gate through GitHub App user auth, webhooks, Queues, Durable Objects, and D1/R2.
- Cloudflare rate-limit bindings are configured for registry, dynamic, strict,
and MCP routes. The public no-key MCP endpoint uses a dedicated
API_MCP_RATE_LIMITbinding with a60 requests/minute/IPproduction cap. In-process limits remain a local/dev fallback when the Worker binding is unavailable. - Worker responses attach security headers in code as well as static asset
headers: CSP, HSTS,
X-Frame-Options,X-Content-Type-Options,Referrer-Policy,Permissions-Policy, andCross-Origin-Opener-Policy. - No public website endpoint may import content into the registry or publish submissions directly. Content PR creation and direct merge decisions are isolated in the private submission gate after public checks and private maintainer review pass.
- Job lead intake is intentionally shallow. Paid job publication remains gated by the token-protected D1 admin flow, which requires enriched reviewed listing content before active paid rows can publish.
Registry Endpoint Change Checklist
Registry API PRs need a separate review path from content-only submission fallbacks. A clean CodeRabbit review or a skipped bot review is not enough for a new or changed registry endpoint. Review these surfaces together:
- Route handler: add or update the thin handler under
apps/web/src/routes/api/**and keep request handling delegated through the central API router. - Contract: add or update the matching route definition in
apps/web/src/lib/api/contracts.ts, including method, path, route id, tags, response schema, error responses, origin-check setting, and rate-limit scope. - Runtime posture: state whether the endpoint is read-only or write-capable, whether browser origin checks apply, which Cloudflare rate-limit binding is used, and whether auth, webhook signatures, payload limits, or content-type checks are required.
- Source logic: keep registry aggregation or lookup behavior in the shared content/server layer rather than duplicating registry traversal in the route file.
- Tests: update
tests/api-contracts.test.tsand focused route/router tests so route coverage, ids, paths, schemas, examples, and error envelopes stay deterministic. - OpenAPI: run
pnpm validate:openapior document why it was not run. Generated files such asapps/web/public/openapi.{json,yaml},apps/web/src/data/openapi.ts, andcloudflare/api-schema-heyclaude-openapi.yamlmust come from the generator; do not hand-edit them. - Reproducibility: for maintainer/internal generation PRs, confirm generator output is reproducible and generated diffs are limited to the endpoint change. For external contributor PRs, prefer source route/contract/test changes and leave generated artifact commits to maintainer automation.
- Linked issue: link the issue being solved, or write an explicit maintainer-lane no-issue rationale in the PR body so advisory bots do not keep surfacing missing-link noise.
Registry Trust Fields
Registry feeds and entry detail payloads may include trustSignals derived from
existing file-backed facts:
- package verification flags, first-party/external trust, and package SHA256
- source URLs already present on the entry
- content/repository/verification timestamps already present on the entry
- generated adapter status and platform compatibility
These fields are factual metadata, not paid ranking or live health claims. Live link health checks can be added later as a separate generated artifact once they are backed by a real checker.