{"openapi":"3.1.0","info":{"title":"Doccupine content API","version":"1.0.0","summary":"Read-only JSON access to doccupine.com: product summary, pricing, page index, page content as Markdown, and keyword search.","description":"Doccupine is an open-source, AI-ready documentation platform. This API exposes the public marketing site to agents and tooling: the same pages a browser sees, as structured JSON and Markdown. No authentication, no rate-limit token, no side effects. For the product itself (creating and deploying documentation sites) use the dashboard at https://doccupine.com/dashboard; for a published documentation site's own MCP server, see https://docs.doccupine.com. Errors are always JSON in the `ApiError` envelope.","termsOfService":"https://doccupine.com/terms-of-service","contact":{"name":"Doccupine","email":"team@doccupine.com","url":"https://doccupine.com/contact"},"license":{"name":"O'Saasy License","url":"https://github.com/doccupine/cli/blob/main/LICENSE"}},"externalDocs":{"description":"Doccupine documentation","url":"https://docs.doccupine.com"},"servers":[{"url":"https://doccupine.com","description":"Production"}],"tags":[{"name":"site","description":"Product summary, pricing, and discovery links."},{"name":"pages","description":"The site's pages as Markdown."},{"name":"search","description":"Keyword search across the site's pages."},{"name":"agents","description":"Machine-readable files and the MCP server."}],"paths":{"/api/v1/site":{"get":{"operationId":"getSite","tags":["site"],"summary":"Get the Doccupine product summary, pricing, and contact details","description":"The entry point. Returns what Doccupine is, the two plans with prices, what every plan includes, the free-trial terms, contact channels, and links to every other machine-readable resource (llms.txt, sitemap, OpenAPI, MCP).","responses":{"200":{"description":"Site summary.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Site"}}}},"405":{"description":"Only GET is supported.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/pages":{"get":{"operationId":"listPages","tags":["pages"],"summary":"List every public page with a Markdown representation","description":"Marketing pages, the comparison pages, and published blog posts. Each entry has the HTML URL, the Markdown URL, a title, and a one-line description. Use `getPage` to fetch a page's Markdown.","responses":{"200":{"description":"Page index.","content":{"application/json":{"schema":{"type":"object","required":["pages"],"properties":{"pages":{"type":"array","items":{"$ref":"#/components/schemas/PageSummary"}}}}}}},"405":{"description":"Only GET is supported.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/pages/{path}":{"get":{"operationId":"getPage","tags":["pages"],"summary":"Get one page as Markdown","description":"Returns the page's Markdown representation: the same text an `Accept: text/markdown` request for the page URL returns. Works for every path listed by `listPages`, including blog posts (`blog/<slug>`).","parameters":[{"name":"path","in":"path","required":true,"description":"Site path of the page without the leading slash, e.g. `about`, `compare/gitbook`, `blog/my-post`. Use `index` for the home page.","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9/-]*$","maxLength":200},"example":"pricing"}],"responses":{"200":{"description":"The page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Page"}}}},"400":{"description":"The path is not a valid site path.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"No page with a Markdown representation at that path.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"405":{"description":"Only GET is supported.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/search":{"get":{"operationId":"searchPages","tags":["search"],"summary":"Search the site's pages by keyword","description":"Keyword search over every page's Markdown, ranked by term overlap per section. Returns the best matching sections with a snippet each. Good for answering questions such as pricing, self-hosting, MCP support, or how Doccupine compares to another platform.","parameters":[{"name":"q","in":"query","required":true,"description":"Search terms, 2 to 200 characters.","schema":{"type":"string","minLength":2,"maxLength":200},"example":"self-host pricing"},{"name":"limit","in":"query","required":false,"description":"Maximum hits to return (1 to 20).","schema":{"type":"integer","minimum":1,"maximum":20,"default":10}}],"responses":{"200":{"description":"Ranked hits, best first. Empty when nothing matches.","content":{"application/json":{"schema":{"type":"object","required":["query","hits"],"properties":{"query":{"type":"string"},"hits":{"type":"array","items":{"$ref":"#/components/schemas/SearchHit"}}}}}}},"400":{"description":"`q` is missing, too short, or `limit` is out of range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"405":{"description":"Only GET is supported.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/mcp":{"post":{"operationId":"mcpRequest","tags":["agents"],"summary":"Model Context Protocol endpoint (Streamable HTTP)","description":"A stateless MCP server over JSON-RPC 2.0. Send `initialize`, then `tools/list`, `tools/call`, `resources/list`, `resources/read`, or `ping` as the request body; each response is a single `application/json` JSON-RPC message. Tools: `search_doccupine`, `get_doccupine_page`, `list_doccupine_pages`, `get_doccupine_pricing`. Manifest: /.well-known/mcp.json. Point an MCP client at this URL with the Streamable HTTP transport; no authentication.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcRequest"}}}},"responses":{"200":{"description":"A JSON-RPC response (or a batch of responses).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcResponse"}}}},"202":{"description":"A notification was accepted; no body."},"400":{"description":"The body is not valid JSON-RPC 2.0.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"413":{"description":"The body exceeds 64 KB.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/openapi.json":{"get":{"operationId":"getOpenApi","tags":["agents"],"summary":"This OpenAPI document","description":"The OpenAPI 3.1 description of the public API, as JSON.","responses":{"200":{"description":"OpenAPI 3.1 document.","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/llms.txt":{"get":{"operationId":"getLlmsTxt","tags":["agents"],"summary":"Site index for LLMs (llms.txt)","description":"Every public page with a one-line description, plus developer resources, in the llms.txt format.","responses":{"200":{"description":"Markdown text.","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/llms-full.txt":{"get":{"operationId":"getLlmsFullTxt","tags":["agents"],"summary":"Full site content bundle for LLMs","description":"Every marketing page concatenated as one Markdown document.","responses":{"200":{"description":"Markdown text.","content":{"text/plain":{"schema":{"type":"string"}}}}}}},"/sitemap.xml":{"get":{"operationId":"getSitemap","tags":["agents"],"summary":"XML sitemap","description":"Every indexable URL on doccupine.com, including blog posts.","responses":{"200":{"description":"Sitemap XML.","content":{"application/xml":{"schema":{"type":"string"}}}}}}},"/.well-known/mcp.json":{"get":{"operationId":"getMcpManifest","tags":["agents"],"summary":"MCP server manifest","description":"Discovery manifest listing the MCP servers Doccupine operates, with transport, endpoint, and tool names.","responses":{"200":{"description":"Manifest JSON.","content":{"application/json":{"schema":{"type":"object"}}}}}}}},"components":{"schemas":{"ApiError":{"type":"object","description":"The error envelope every failing `/api/*` response uses. `code` is stable and machine-readable, `message` says what happened, `hint` says what to do.","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["not_found","method_not_allowed","invalid_request","not_acceptable","payload_too_large","forbidden","internal_error"]},"message":{"type":"string"},"hint":{"type":"string"},"details":{"type":"object","additionalProperties":true}}}},"example":{"error":{"code":"not_found","message":"No page with a Markdown representation at /nope.","hint":"List pages with GET /api/v1/pages."}}},"PricingPlan":{"type":"object","required":["id","name","priceUsdPerMonth","projects","teamMembers","includedAiBudgetUsdPerMonth"],"properties":{"id":{"type":"string","enum":["pro","enterprise"]},"name":{"type":"string"},"priceUsdPerMonth":{"type":"number"},"projects":{"type":"integer"},"teamMembers":{"oneOf":[{"type":"integer"},{"type":"string","enum":["unlimited"]}]},"includedAiBudgetUsdPerMonth":{"type":"number"}}},"Site":{"type":"object","required":["name","url","summary","contact","pricing","links"],"properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri"},"summary":{"type":"string"},"contact":{"type":"object","properties":{"email":{"type":"string","format":"email"},"discord":{"type":"string","format":"uri"},"github":{"type":"string","format":"uri"},"page":{"type":"string","format":"uri"}}},"pricing":{"type":"object","required":["currency","plans","freeTrial"],"properties":{"currency":{"type":"string"},"billing":{"type":"string"},"freeTrial":{"type":"object","properties":{"days":{"type":"integer"},"creditCardRequired":{"type":"boolean"}}},"plans":{"type":"array","items":{"$ref":"#/components/schemas/PricingPlan"}},"includedOnEveryPlan":{"type":"array","items":{"type":"string"}},"page":{"type":"string","format":"uri"}}},"links":{"type":"object","additionalProperties":{"type":"string","format":"uri"}},"developerResources":{"type":"array","items":{"type":"object","required":["title","url","description"],"properties":{"title":{"type":"string"},"url":{"type":"string","format":"uri"},"description":{"type":"string"}}}}}},"PageSummary":{"type":"object","required":["path","url","title","description","markdownUrl","kind"],"properties":{"path":{"type":"string","example":"/pricing"},"url":{"type":"string","format":"uri"},"title":{"type":"string"},"description":{"type":"string"},"markdownUrl":{"type":"string","format":"uri"},"kind":{"type":"string","enum":["page","blog-post"]}}},"Page":{"type":"object","required":["path","url","markdown"],"properties":{"path":{"type":"string"},"url":{"type":"string","format":"uri"},"markdown":{"type":"string","description":"The page as Markdown."}}},"SearchHit":{"type":"object","required":["path","url","title","section","snippet","score"],"properties":{"path":{"type":"string"},"url":{"type":"string","format":"uri"},"title":{"type":"string"},"section":{"type":"string"},"snippet":{"type":"string"},"score":{"type":"number"}}},"JsonRpcRequest":{"type":"object","required":["jsonrpc","method"],"properties":{"jsonrpc":{"type":"string","enum":["2.0"]},"id":{"oneOf":[{"type":"string"},{"type":"integer"}]},"method":{"type":"string","example":"tools/list"},"params":{"type":"object","additionalProperties":true}}},"JsonRpcResponse":{"type":"object","required":["jsonrpc","id"],"properties":{"jsonrpc":{"type":"string","enum":["2.0"]},"id":{"oneOf":[{"type":"string"},{"type":"integer"},{"type":"null"}]},"result":{"type":"object","additionalProperties":true},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"},"data":{}}}}}}}}