API JSON
A API JSON somente leitura que todo site Blume serve — índice de páginas, documentos por página, navegação, busca — e a descrição OpenAPI 3.1 que permite a frameworks de function calling construírem ferramentas a partir dela.
Todo site Blume também serve sua documentação como uma pequena API JSON somente leitura — a gêmea REST das ferramentas do servidor MCP, sobre o mesmo snapshot de páginas, para agentes e frameworks de function calling que falam HTTP puro em vez de MCP. Ela vem ligada por padrão e não precisa de configuração:
| Endpoint | Retorna |
|---|---|
/api/docs/pages.json |
Todas as páginas com sua rota, título, descrição, tipo de conteúdo, idioma, facetas e as URLs de suas formas renderizada, Markdown e JSON. |
/api/docs/pages/{route}.json |
Uma página: sua entrada no índice mais o Markdown para agentes (o mesmo corpo que get_page retorna). {route} é a rota da página sem a barra inicial, index para a home. |
/api/docs/navigation.json |
A árvore de navegação — abas do cabeçalho e a hierarquia da barra lateral. |
/api/docs/search?q= |
Busca em texto completo, com o mesmo escopo de limit, contentTypes, locale, version e filters[key] que search_docs. Somente em saída de servidor. |
/openapi.json |
A descrição OpenAPI 3.1 de toda a superfície legível por máquina. |
O índice de páginas, os documentos por página e a navegação são pré-renderizados, então um site estático os serve como arquivos a partir de qualquer host. A busca é um endpoint ao vivo e existe apenas sob saída de servidor, onde ela roda o mesmo índice que search_docs usa.
Erros
Os erros são problem details no formato RFC 9457 (application/problem+json) com um code estável, um detail e uma dica de resolution dizendo ao agente para onde ir em seguida — uma página inexistente, uma consulta de busca em branco ou, em saída de servidor, qualquer URL /api/… que nenhum endpoint responde:
{
"code": "API_ROUTE_NOT_FOUND",
"detail": "No API route exists at /api/nope.",
"instance": "/api/nope",
"links": [
{
"href": "https://docs.example.com/openapi.json",
"label": "OpenAPI description"
},
{
"href": "https://docs.example.com/api/docs/pages.json",
"label": "Page index"
}
],
"resolution": "Discover the available operations through the OpenAPI description at https://docs.example.com/openapi.json, or list every page at https://docs.example.com/api/docs/pages.json.",
"status": 404,
"title": "API route not found",
"type": "about:blank"
}
Descrição OpenAPI
O documento OpenAPI em /openapi.json é gerado a cada build a partir da sua config, então ele descreve apenas o que o site publicado serve: todo endpoint JSON com um operationId único, parâmetros tipados e schemas de resposta, além das superfícies de texto ao lado — os espelhos .md, llms.txt e llms-full.txt, agent-readability.json — e o endpoint MCP quando ele está habilitado. Frameworks que constroem ferramentas a partir de uma descrição OpenAPI ganham o mesmo alcance que um cliente MCP tem. O documento é referenciado a partir do catálogo de APIs, do manifesto de legibilidade, do cabeçalho Link da homepage como rel="service-desc" e do llms.txt.
Nada disso mexe na sua própria referência de API: uma spec documentada é renderizada em páginas, nunca servida em /openapi.json, e o catálogo lista as duas. Um public/openapi.json que você mesmo publica assume aquela rota (os endpoints JSON continuam). O catch-all de /api/… sai do caminho quando uma seção da documentação é servida a partir do namespace /api (content/api/overview.md) ou quando uma página personalizada é dona de uma rota rest sob /api/, então essas páginas continuam vencendo.
Desligando
Defina ai.api como false para não publicar nada disso:
ai: {
api: false,
}