{"openapi":"3.1.0","info":{"title":"CustomClaw Registry API","version":"1.0.0","description":"CustomClaw is a registry of drop-in developer utilities agents can install on behalf of their users. Use GET /api/catalog to discover available utilities, then GET /api/cli?slug=<slug> to fetch the actual payload. Free utilities are public; paid utilities require a completed Stripe checkout session_id.","contact":{"name":"CustomClaw","url":"https://customclaw.company"}},"servers":[{"url":"https://customclaw.company"}],"paths":{"/api/catalog":{"get":{"operationId":"getCatalog","summary":"List every utility in the registry","description":"Returns a machine-readable list of every utility CustomClaw offers, including slug, name, description, price (cents), required tier, and install command. No authentication required. Use this to discover what can be installed, then call /api/cli to fetch a specific payload.","responses":{"200":{"description":"Catalog payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Catalog"}}}}}}},"/api/cli":{"get":{"operationId":"fetchUtility","summary":"Fetch a utility's files and dependencies by slug","description":"Returns the files and dependency list for a single utility. Free utilities (requiredTier = 0) are open. Paid utilities require a session_id query parameter proving a completed Stripe checkout for that slug. Pass download=1 to stream the payload as a file attachment (single-file tools come back as text/plain; multi-file bundles come back as a JSON manifest with Content-Disposition: attachment).","parameters":[{"name":"slug","in":"query","required":true,"description":"Utility slug as listed in /api/catalog (e.g. `token-optimiser`, `json-repair`).","schema":{"type":"string"}},{"name":"session_id","in":"query","required":false,"description":"Stripe Checkout Session ID proving purchase. Required only for utilities where requiredTier > 0. Sessions are valid for one year after checkout.","schema":{"type":"string"}},{"name":"download","in":"query","required":false,"description":"Set to `1` to stream the payload as a file attachment (Content-Disposition: attachment) instead of a JSON body.","schema":{"type":"string","enum":["1"]}}],"responses":{"200":{"description":"Utility payload. If `download=1`, the response is an attachment (text/plain for single-file tools, application/json manifest for multi-file bundles). Otherwise the response is the JSON payload below.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UtilityPayload"}},"text/plain":{"schema":{"type":"string","description":"Raw file content (only when download=1 and the utility is a single file)."}}}},"401":{"description":"Paid utility requested without a valid session_id, or the session does not authorize this slug / is unpaid / is older than the 1-year validity window.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Unknown slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Payload failed to load from disk, or the slug has no associated payload.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"Catalog":{"type":"object","required":["version","site","cli","utilities"],"properties":{"version":{"type":"integer","description":"Catalog schema version.","examples":[1]},"site":{"type":"string","format":"uri","examples":["https://customclaw.company"]},"cli":{"type":"object","description":"Metadata for the optional `customclaw-cli` npm package (alternative to calling /api/cli directly).","required":["package","install","fetchEndpoint","authHeader"],"properties":{"package":{"type":"string","examples":["customclaw-cli"]},"install":{"type":"string","examples":["npx customclaw-cli"]},"fetchEndpoint":{"type":"string","format":"uri","examples":["https://customclaw.company/api/cli"]},"authHeader":{"type":"string","examples":["Authorization: Bearer <apiKey>"]}}},"utilities":{"type":"array","items":{"$ref":"#/components/schemas/CatalogUtility"}}}},"CatalogUtility":{"type":"object","required":["slug","name","tagline","description","tags","stack","difficulty","priceCents","requiredTier","free","installCommand","detailUrl"],"properties":{"slug":{"type":"string","description":"URL-safe identifier. Pass this to /api/cli?slug=.","examples":["token-optimiser"]},"name":{"type":"string","examples":["Token Optimiser"]},"tagline":{"type":"string"},"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"stack":{"type":"array","items":{"type":"string"},"description":"Languages/frameworks the utility is written for."},"difficulty":{"type":"string","enum":["Beginner","Intermediate","Advanced"]},"priceCents":{"type":"integer","minimum":0,"description":"Price in USD cents. 0 means free."},"requiredTier":{"type":"integer","minimum":0,"description":"0 = free, no auth required. >0 = paid, requires a completed Stripe checkout session_id."},"free":{"type":"boolean","description":"Convenience flag; true iff requiredTier === 0."},"installCommand":{"type":"string","examples":["npx customclaw-cli add token-optimiser"]},"detailUrl":{"type":"string","format":"uri","examples":["https://customclaw.company/utilities/token-optimiser"]}}},"UtilityPayload":{"type":"object","required":["files","dependencies","message"],"properties":{"files":{"type":"array","description":"The files to write into the user's project. Each file's `path` is relative to the project root.","items":{"$ref":"#/components/schemas/UtilityFile"}},"dependencies":{"type":"array","description":"npm package names the utility needs (may be empty for stdlib-only Python tools).","items":{"type":"string"}},"message":{"type":"string","description":"Human-readable confirmation of what was installed and where."}}},"UtilityFile":{"type":"object","required":["path","content"],"properties":{"path":{"type":"string","description":"Destination path relative to the consuming project's root.","examples":["llm_tools/token_optimiser.py"]},"content":{"type":"string","description":"Raw file contents."}}},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","examples":["Utility not found"]},"message":{"type":"string"},"details":{"type":"string"}}}}}}