{"openapi":"3.1.0","info":{"title":"BoardUI API","version":"1.0.0","summary":"The component registry, license API, and MCP endpoint behind boardui.com.","description":"BoardUI is a React + Tailwind CSS v4 design system for dashboards and agentic interfaces.\nComponents ship as source you own rather than as a runtime package, so \"installing\" one means fetching its registry JSON and writing the files it carries into a project.\n\n## When to use this API\n\n- **Building or restyling a React dashboard, admin panel, or agent/chat UI.** Fetch `/r/registry.json` for the catalogue, then `/r/{name}.json` for a component's full source and its npm dependencies.\n- **You need one component, not a framework.** Each item is self-contained; `registryDependencies` lists the other BoardUI items to fetch first.\n- **A coding agent is doing the work.** The MCP endpoint at `/mcp` exposes the same catalogue as tools over Streamable HTTP, and `npx -y boardui@latest mcp` runs the fuller stdio server that can also write files locally.\n- **Checking or activating a BoardUI Pro license.** The `/api/licenses/*` endpoints are wire-compatible with the Lemon Squeezy License API.\n\n## When not to use it\n\nThis is not a hosted UI service: there is nothing to call at runtime, no component rendering endpoint, and no per-request billing. Fetch source once, commit it, and the API is out of the loop.\n\n## Authentication\n\nEverything under `/r/` is public and unauthenticated. Only `/api/pro/r/{name}` requires a license key, sent as `Authorization: Bearer <key>`.\n\n## Rate limits\n\nNo per-key quota is enforced. The registry is static JSON served from a CDN and may be fetched freely; please cache it rather than refetching per file. The license endpoints talk to a database and should be called at install time, not per request.\n\n## Content negotiation\n\nDocumentation pages on https://www.boardui.com also answer `Accept: text/markdown` with a clean markdown rendering of the same URL. See https://www.boardui.com/llms.txt for the site map.","contact":{"name":"BoardUI","url":"https://www.boardui.com"},"license":{"name":"MIT (free tier component source)","identifier":"MIT"}},"servers":[{"url":"https://www.boardui.com","description":"Production"}],"tags":[{"name":"Registry","description":"The public component catalogue: names, metadata, and complete source."},{"name":"Pro","description":"License-gated Pro component source."},{"name":"Licenses","description":"Activate, validate, and deactivate BoardUI Pro license keys."},{"name":"Agents","description":"Machine-readable descriptions of the site itself."},{"name":"Site","description":"Small helpers the boardui.com front end calls."}],"paths":{"/r/registry.json":{"get":{"operationId":"getRegistryIndex","tags":["Registry"],"summary":"List every free component","description":"The catalogue of installable free items: name, type, title, description, and dependencies, without file contents. Start here to discover exact item names, then fetch each one from /r/{name}.json. Pro items are deliberately absent — see /r/registry-pro.json.","responses":{"200":{"description":"The registry index.","content":{"application/json":{"schema":{"type":"object","required":["name","homepage","items"],"properties":{"$schema":{"type":"string","format":"uri"},"name":{"type":"string","examples":["boardui"]},"homepage":{"type":"string","format":"uri"},"items":{"type":"array","items":{"$ref":"#/components/schemas/RegistryItem"}}}}}}}}}},"/r/registry-pro.json":{"get":{"operationId":"getProRegistryIndex","tags":["Registry","Pro"],"summary":"List every Pro component and template","description":"Metadata for Pro items — title, description, and the public usage example shown on the docs page. Never carries source; fetching that needs a license and /api/pro/r/{name}.","responses":{"200":{"description":"The Pro index.","content":{"application/json":{"schema":{"type":"object","required":["items"],"properties":{"items":{"type":"array","items":{"type":"object","required":["name","title","description"],"properties":{"name":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"kind":{"type":"string","enum":["component","template"]},"title":{"type":"string"},"description":{"type":"string"},"example":{"type":"string","description":"Public usage example, as TSX."}}}}}}}}}}}},"/r/{name}.json":{"get":{"operationId":"getRegistryItem","tags":["Registry"],"summary":"Get one free component with its full source","description":"Everything needed to install a free item: complete file contents, version-pinned npm dependencies, the BoardUI items it depends on, and its docs usage examples. Install `registryDependencies` before writing these files.","parameters":[{"name":"name","in":"path","required":true,"description":"Item name from /r/registry.json, without the .json suffix.","schema":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"examples":{"button":{"value":"button"},"dataTable":{"value":"data-table"}}}],"responses":{"200":{"description":"The item, with source inlined.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistryItem"}}}},"404":{"description":"No free item by that name. It may be a Pro item — check /r/registry-pro.json.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/pro/r/{name}":{"get":{"operationId":"getProRegistryItem","tags":["Pro"],"summary":"Get one Pro component with its full source","description":"The licensed counterpart of /r/{name}.json. Requires a BoardUI Pro license key; the response is marked no-store so paid source never lands in a shared cache.","security":[{"licenseKey":[]}],"parameters":[{"name":"name","in":"path","required":true,"description":"Pro item name from /r/registry-pro.json.","schema":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$"},"examples":{"composer":{"value":"composer"}}},{"name":"X-BoardUI-Instance","in":"header","required":false,"description":"Activation instance id from /api/licenses/activate. Sent by `boardui login` so a seat can be attributed.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The Pro item, with source inlined.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistryItem"}}}},"401":{"description":"Missing or invalid license key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key is valid but not entitled to this item, or its seat limit is used up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No Pro item by that name.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/licenses/activate":{"post":{"operationId":"activateLicense","tags":["Licenses"],"summary":"Activate a license key on one machine","description":"Claims a seat and returns an instance id. Store that id: /api/licenses/validate and /api/licenses/deactivate both take it. Wire-compatible with Lemon Squeezy's POST /v1/licenses/activate.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["license_key","instance_name"],"properties":{"license_key":{"type":"string","description":"The customer's license key."},"instance_name":{"type":"string","description":"A label for this machine, e.g. the hostname."}}}}}},"responses":{"200":{"description":"Activated, or refused with a reason in `error`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LicenseResponse"}}}},"400":{"description":"`license_key` or `instance_name` missing, or the key could not be activated.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/licenses/validate":{"post":{"operationId":"validateLicense","tags":["Licenses"],"summary":"Check whether a license key is still valid","description":"Reports the key's status and seat usage. Pass `instance_id` to also confirm this machine's activation is still live. Wire-compatible with Lemon Squeezy's POST /v1/licenses/validate.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["license_key"],"properties":{"license_key":{"type":"string"},"instance_id":{"type":"string","format":"uuid","description":"Instance id from activation. Optional; omit to check the key alone."}}}}}},"responses":{"200":{"description":"The key's current state.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LicenseResponse"}}}},"400":{"description":"`license_key` missing, or the key is unknown.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/licenses/deactivate":{"post":{"operationId":"deactivateLicense","tags":["Licenses"],"summary":"Release a seat held by one machine","description":"Frees the activation so the seat can be used elsewhere. Wire-compatible with Lemon Squeezy's POST /v1/licenses/deactivate.","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","required":["license_key","instance_id"],"properties":{"license_key":{"type":"string"},"instance_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Deactivated, or refused with a reason in `error`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LicenseResponse"}}}},"400":{"description":"`license_key` or `instance_id` missing, or the instance is already gone.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/mcp":{"post":{"operationId":"callMcpEndpoint","tags":["Agents"],"summary":"MCP endpoint (Streamable HTTP)","description":"Model Context Protocol over Streamable HTTP, exposing the registry as read-only tools: list_components, search_components, get_component, get_usage_examples, and get_theme. Stateless — no session id is issued, so no Mcp-Session-Id is needed on later calls. Send `Accept: application/json, text/event-stream`. For installs, project init, and licensing, run the fuller stdio server with `npx -y boardui@latest mcp`.","parameters":[{"name":"MCP-Protocol-Version","in":"header","required":false,"description":"Negotiated protocol version. Omitted on the initialize call; assumed to be 2025-03-26 if never sent.","schema":{"type":"string","examples":["2025-06-18"]}}],"requestBody":{"required":true,"description":"A single JSON-RPC 2.0 request, notification, or response.","content":{"application/json":{"schema":{"type":"object","required":["jsonrpc"],"properties":{"jsonrpc":{"type":"string","const":"2.0"},"id":{"type":["string","number"],"description":"Present on requests, absent on notifications."},"method":{"type":"string","examples":["tools/list"]},"params":{"type":"object","additionalProperties":true}}}}}},"responses":{"200":{"description":"The JSON-RPC response to a request.","content":{"application/json":{"schema":{"type":"object","required":["jsonrpc","id"],"properties":{"jsonrpc":{"type":"string","const":"2.0"},"id":{"type":["string","number","null"]},"result":{"type":"object","additionalProperties":true},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"integer","description":"JSON-RPC error code."},"message":{"type":"string"},"data":{"description":"Optional detail."}}}}}}}},"202":{"description":"A notification or response was accepted. No body."},"400":{"description":"Malformed JSON-RPC, or an unsupported MCP-Protocol-Version.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"406":{"description":"The Accept header lists neither application/json nor text/event-stream.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"openMcpStream","tags":["Agents"],"summary":"Open a server-to-client MCP stream","description":"Not offered: this server is stateless and never initiates messages, so a GET asking for text/event-stream is answered 405, as the transport spec allows. A GET from a browser gets the human documentation page instead.","responses":{"200":{"description":"The /mcp documentation page, for a client that asked for HTML.","content":{"text/html":{"schema":{"type":"string"}}}},"405":{"description":"No SSE stream is offered at this endpoint.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/openapi.json":{"get":{"operationId":"getOpenApiDocument","tags":["Agents"],"summary":"This document","description":"The OpenAPI 3.1 description of the BoardUI API. Also served at /api/openapi.json.","responses":{"200":{"description":"The OpenAPI document.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"description":"An OpenAPI 3.1 document."}}}}}}},"/llms.txt":{"get":{"operationId":"getLlmsTxt","tags":["Agents"],"summary":"Site map for language models","description":"The llmstxt.org index: what BoardUI is, when to reach for it, and a linked map of every docs page and component. Cheaper to read than crawling the site.","responses":{"200":{"description":"The llms.txt document.","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/llms-full.txt":{"get":{"operationId":"getLlmsFullTxt","tags":["Agents"],"summary":"Every component's docs in one file","description":"The llms.txt companion with each item's description, install command, and usage examples inlined — the whole catalogue in one fetch instead of ~70 page loads.","responses":{"200":{"description":"The llms-full.txt document.","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/api/github/stars":{"get":{"operationId":"getStarterRepoStars","tags":["Site"],"summary":"Star count for the starter repository","description":"Proxies GitHub so visitors never hit its per-IP rate limit. Cached for an hour; answers `{ \"stars\": null }` rather than an error when GitHub is unreachable.","responses":{"200":{"description":"The star count, or null when it could not be read.","content":{"application/json":{"schema":{"type":"object","required":["stars"],"properties":{"stars":{"type":["integer","null"],"description":"Stargazers, or null on any upstream failure."}}}}}}}}},"/api/geo":{"get":{"operationId":"getConsentRequirement","tags":["Site"],"summary":"Whether this visitor needs cookie consent","description":"Answers from the request IP's country whether ePrivacy-style prior consent applies (EU, EEA, UK). The site's analytics gate on this. Never cached, and fails closed when the country cannot be resolved.","responses":{"200":{"description":"The consent requirement for this request.","content":{"application/json":{"schema":{"type":"object","required":["consentRequired","country"],"properties":{"consentRequired":{"type":"boolean"},"country":{"type":["string","null"],"description":"ISO 3166-1 alpha-2 country, or null when unresolved."}}}}}}}}}},"components":{"securitySchemes":{"licenseKey":{"type":"http","scheme":"bearer","description":"A BoardUI Pro license key, sent as `Authorization: Bearer <key>`. Obtained at https://www.boardui.com/pricing and stored locally by `boardui login`."}},"schemas":{"RegistryItem":{"type":"object","description":"One installable registry item, in the shadcn registry-item schema. `files[].content` carries the complete source, so a client can write the files itself without a second request.","required":["name","type","title","description","files"],"properties":{"$schema":{"type":"string","format":"uri","description":"shadcn registry-item schema URL."},"name":{"type":"string","pattern":"^[a-z0-9]+(?:-[a-z0-9]+)*$","description":"Install name, e.g. `button`. Stable across releases.","examples":["button"]},"type":{"type":"string","description":"shadcn item type.","enum":["registry:ui","registry:block","registry:lib","registry:style","registry:hook","registry:file"]},"boarduiType":{"type":"string","enum":["base","application","foundations"],"description":"BoardUI's own grouping, used by the docs nav and `boardui list`."},"title":{"type":"string","description":"Human-readable name."},"description":{"type":"string","description":"One sentence on what the item is."},"dependencies":{"type":"array","items":{"type":"string"},"description":"npm packages to install, version-pinned, e.g. `react-aria-components@^1.17.0`."},"registryDependencies":{"type":"array","items":{"type":"string"},"description":"Other BoardUI item names this one needs. Install them first."},"files":{"type":"array","description":"Source files to write into the consuming project.","items":{"type":"object","required":["path","type"],"properties":{"path":{"type":"string","description":"Path inside the BoardUI repo."},"target":{"type":"string","description":"Where to write it in the consuming project, when it differs from `path`."},"type":{"type":"string","description":"shadcn file type."},"content":{"type":"string","description":"Complete file source. Absent in the index, present in item responses."}}}},"meta":{"type":"object","description":"Docs material lifted from the component's page at build time.","properties":{"docsUrl":{"type":"string","format":"uri"},"example":{"type":"string","description":"The main usage example, as TSX."},"snippets":{"type":"array","items":{"type":"object","required":["label","code"],"properties":{"label":{"type":"string","description":"Section name, e.g. `variants`."},"code":{"type":"string","description":"TSX snippet."}}}}}}}},"LicenseResponse":{"type":"object","description":"Wire-compatible with the Lemon Squeezy License API response, so a client written against that API works here by changing one base URL.","required":["error"],"properties":{"activated":{"type":"boolean","description":"Present on /activate."},"validated":{"type":"boolean","description":"Present on /validate (as `valid`)."},"valid":{"type":"boolean","description":"Whether the key is currently valid."},"deactivated":{"type":"boolean","description":"Present on /deactivate."},"error":{"type":["string","null"],"description":"Null on success; the failure reason otherwise."},"license_key":{"type":"object","properties":{"status":{"type":"string","enum":["active","inactive","expired","disabled"]},"activation_limit":{"type":"integer","description":"Seats the license allows."},"activation_usage":{"type":"integer","description":"Seats currently in use."}}},"instance":{"type":"object","description":"The activated machine. Store `id` — deactivation needs it.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}},"meta":{"type":"object","properties":{"product_id":{"type":"integer"},"product_name":{"type":"string"}}}}},"Error":{"type":"object","description":"The error envelope every endpoint answers failures with. Branch on `code`; show `message`; act on `hint`.","required":["error","code","message","hint","docs"],"properties":{"error":{"type":"string","description":"The same text as `message`. Retained for clients written against the pre-1.0 shape."},"code":{"type":"string","description":"Stable machine-readable code. New values may be added over time.","enum":["not_found","method_not_allowed","not_acceptable","invalid_request","unauthorized","forbidden","rate_limited","upstream_error","internal_error"]},"message":{"type":"string","description":"What went wrong, in one sentence."},"hint":{"type":"string","description":"What the caller should do next."},"docs":{"type":"string","format":"uri","description":"Where this endpoint's contract is documented."}}}}},"externalDocs":{"description":"BoardUI documentation","url":"https://www.boardui.com/docs/introduction"}}