Cookbook REST
Receitas funcionais contra a API viva do engine: cada campo verificado contra a spec em execução.
Todo exemplo aqui roda contra o engine hospedado em https://valorbrain-api.valor.digital.
Os mesmos paths funcionam no seu engine on-premise (Enterprise; porta padrão :7438 na sua rede).
Os nomes de campo vêm da spec que o próprio engine serve em /openapi.json — se esta página e a spec divergirem, a spec vence (um rebuild regenera as páginas de referência a partir dela).
Autenticação e tenancy
Authorization: Bearer <token>Credenciais de cliente aceitas no REST do engine:
| Credencial | Formato | O que é |
|---|---|---|
| Token MCP | vbm_… | A credencial do cliente, a mesma do MCP. Vem no signup (mcp_token) ou é criada em Configurações → Tokens MCP. |
| Chave de conta de agente (legado) | vb_agent_… | A api_key do signup (npx -y @valorbrain/cli@latest init --agent). Vale no REST e no claim; no MCP volta 401 wrong_credential_type. |
O tenant vem sempre da credencial: não envie X-Tenant-ID. Nenhuma credencial
de cliente abre as rotas de administração, de crédito e assinatura ou
/metrics. Os exemplos usam $VALORBRAIN_MCP_TOKEN (um vbm_); com a chave
legada, use $VALORBRAIN_API_KEY. A matriz completa está em
Tokens e cada código de erro em
Catálogo de erros.
Checagem rápida de liveness — sem autenticação:
curl -sS https://valorbrain-api.valor.digital/healthzEscrever um documento
curl -sS -X POST https://valorbrain-api.valor.digital/documents \
-H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"collection": "team-notes",
"path": "2026-08-31/deploy-openapi",
"title": "OpenAPI served live from routes[]",
"content": "The engine now generates /openapi.json from the routes table at request time. servers[] is rewritten from VALORBRAIN_PUBLIC_URL.",
"content_type": "milestone",
"confidence": 0.9,
"quality_score": 0.8,
"metadata": {"repo": "valorbrain", "sha": "a34e288d"}
}'Campos do request (todos verificados contra a spec):
| Campo | Tipo | Obrigatório | Default | Notas |
|---|---|---|---|---|
collection | string | sim | — | Namespace; por tenant |
path | string | sim | — | Único dentro da coleção; mesmo path re-serve o mesmo documento |
content | string | sim | — | Máx. 1 MB |
title | string | não | — | |
content_type | string | não | note | Livre; o SaaS cura um vocabulário (note, decision, problem, milestone, …) |
confidence | number | não | 0.5 | 0–1; alimenta o ranking e o gating de consolidação |
quality_score | number | não | 0.5 | 0–1 |
metadata | object | não | — | JSON arbitrário, consultável |
user_id | string | não | — | Atribuição |
run_id | string | não | — | Agrupa writes de uma sessão/job |
event_at | string | não | — | Quando o evento aconteceu (vs. hora do write) |
event_type | string | não | — |
O Document que volta carrega: id, hash, collection, path, title, content_type, visibility, embed_state, is_pinned, page_type, created_at, updated_at.
Três comportamentos que surpreendem:
- Embedding é assíncrono. O write volta imediatamente;
embed_statevai depending → synced(oufailedcomembed_error). Busca que inclui a perna densa só vê o documento quando ele está sincronizado. Faça polling emGET /documents?collection=...se precisar esperar por isso. - Conteúdo é deduplicado por hash. Os mesmos bytes não são indexados duas vezes — inclusive entre coleções (dedup cross-collection é deliberado). Mude o
pathou o conteúdo, não só o título. visibilitydistingue memória compartilhada do tenant de memória privada (sensitivity: private). Documentos privados são ocultados dos outros usuários do tenant — não é só questão de ficarem sem atribuição.
Ler: buscar, recuperar ou perguntar
Três portas, um índice:
| Endpoint | Quando usar | O que devolve |
|---|---|---|
POST /search | O ranking é problema seu; você quer a lista de hits | Resultados ranqueados com scores e snippets |
POST /retrieve | Você quer auto-roteamento e uma chamada para a maioria das perguntas | Resultados ranqueados, sensíveis ao modo |
POST /ask | Você quer uma resposta, não documentos | Resposta de LLM com citações das fontes (suporta stream) |
Busca híbrida
curl -sS -X POST https://valorbrain-api.valor.digital/search \
-H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"q": "how does dedup across collections behave",
"collection": "team-notes",
"limit": 10,
"mode": "hybrid",
"diverse": true
}'q(obrigatório) — a consulta.mode—auto(padrão),keyword,semantic,causal,hybrid. O pipeline de produção é BM25 (pt/en) + vetores densos + RRF + rerank com cross-encoder + MMR (detalhes);modepolariza quais pernas dominam.expand— força liga/desliga da expansão de consulta estilo HyDE. Deixe sem setar e o servidor decide.diverse(padrãotrue) — filtro de diversidade MMR, para que dez hits não sejam dez paráfrases de um documento só.offset— paginação.
Perfis e timing
Dois knobs de request que as páginas de referência carregam mas o resumo da spec não detalha:
"profile": "speed"em/search— o caminho rápido (hybrid/FTS, sem cross-encoder). O padrão ébalanced. Usespeedem consultas interativas tecla-a-tecla onde 100 ms importam mais do que os últimos pontos de ranking."timing": true(ou headerx-search-timing: 1) — adicionahybrid_ms,rerank_ms,graph_msetotal_msà resposta. Quando a recuperação parece lenta, isso diz qual perna antes de você chutar.
Recuperação unificada
curl -sS -X POST https://valorbrain-api.valor.digital/retrieve \
-H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN" \
-H "Content-Type: application/json" \
-d '{"q": "why did we switch the embedding model", "mode": "auto", "limit": 12}'mode adiciona timeline e discovery ao conjunto de busca — auto roteia perguntas de porquê para causal, perguntas de quando para timeline, perguntas de vizinhança para similar-docs. É o mesmo cérebro que memory_prepare usa no lado MCP: uma consulta bem-formulada vale mais que cinco quase-duplicadas.
Resposta RAG
curl -sS -X POST https://valorbrain-api.valor.digital/ask \
-H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN" \
-H "Content-Type: application/json" \
-d '{"q": "What is the document cap for one write?", "collection": "team-notes", "limit": 8}'Campos: q, collection, limit, language, stream. A resposta cita os documentos que usou; trate a lista de citações como o contrato, não a prosa.
Feche o loop: memory_used
Depois de responder com memória recuperada, declare o que você realmente usou:
curl -sS -X POST https://valorbrain-api.valor.digital/api/v1/memory/used \
-H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN" \
-H "Content-Type: application/json" \
-d '{"docids": ["#ab12cd", "#ef4567"], "verdict": "confirmed", "note": "answer relied on the dedup doc"}'docids— os documentos que sustentaram a resposta.verdict—confirmedquando o usuário concordou com o que a memória disse,correctedquando ele rebateu. O loop de feedback é o que faz o ranking aprender; uma recuperação não declarada é uma recuperação desperdiçada.note— texto livre.
Curar: pin, snooze, forget
Os três são POSTs no id do documento (corpos vazios):
curl -sS -X POST https://valorbrain-api.valor.digital/documents/$DOC_ID/pin \
-H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN"
curl -sS -X POST .../documents/$DOC_ID/snooze \
-H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN"
curl -sS -X POST .../documents/$DOC_ID/forget \
-H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN"- pin — boost permanente de prioridade; o documento aparece acima do decaimento do ranking.
- snooze — oculta por N dias (un-snooze reverte). Use quando uma memória está errada agora mas a fonte será corrigida (uma migration em andamento, uma config velha).
- forget — remove a memória. Prefira isso a dar
pinno oposto: um fato corrigido junto do original superseded é um conflito futuro.
Visão do lifecycle (contagens de archived/forgotten/pinned/snoozed e política):
curl -sS https://valorbrain-api.valor.digital/lifecycle/status -H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN"POST /lifecycle/sweep roda as políticas (dry-run por padrão — confira a resposta antes de purgar), POST /lifecycle/restore traz de volta documentos auto-arquivados (forgets manuais continuam apagados).
Confiança: conflitos e decisões
Conflitos
curl -sS ".../api/v1/conflicts?status=open" -H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN"
curl -sS -X POST .../api/v1/conflicts/detect -H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN"
curl -sS -X POST .../api/v1/conflicts/resolve -H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN" \
-H "Content-Type: application/json" -d '{"conflict_id": "...", "strategy": "most_recent"}'Conflitos de valor (mesma chave, valores diferentes), conflitos temporais (fatos expirados ainda afirmados), conflitos de relacionamento. Existem sete estratégias de resolução; most_recent e credibility_weighted cobrem a maioria dos casos reais. A detecção também roda automaticamente no tick de consolidação.
Decisões
curl -sS -X POST .../api/v1/decisions -H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"category": "architecture",
"scenario": "serving OpenAPI",
"reasoning": "static YAML drifts from routes; generate from the running table",
"outcome": "live spec merged with YAML contract",
"confidence": 0.85
}'Companheiros: POST /api/v1/decisions/relations (caused / influenced / precedent_for), GET /api/v1/decisions/chain (caminha uma cadeia causal), GET /api/v1/decisions/similar (busca semântica de precedentes), GET /api/v1/decisions/impact (o que uma decisão tocou a jusante). Registros são hash-chained — a trilha de auditoria é à prova de adulteração por construção.
Medir: uso e valor
curl -sS ".../reports/usage" -H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN"
curl -sS ".../api/v1/usage/answers" -H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN"
curl -sS ".../api/v1/tenant/value-summary" -H "Authorization: Bearer $VALORBRAIN_MCP_TOKEN"O ledger de uso registra cada operação por canal (mcp / rest / hook / cli) com latência e contagens de resultado; value-summary serve o pré-agregado diário (stale_days reporta buracos enquanto o dia de hoje agrega ao vivo). São os endpoints que os dashboards do SaaS leem — mesmos dados, sem camada de interpretação no meio.
REST vs MCP
Tudo acima é REST. As ferramentas MCP (catálogo gerado: memory_retrieve, memory_store, decisions, conflicts, kg_query, …) são uma superfície diferente sobre o mesmo engine, com ergonomia mais rica (expansão de consulta server-side, budgets de snippet, identidade do agente pelos cabeçalhos do contrato (X-Source-Agent)). Se o seu cliente fala MCP, prefira — veja Ferramentas MCP e os schemas completos. Se fala só HTTP, esta página é o jogo inteiro.
Falhas comuns
| Sintoma | Causa | Correção |
|---|---|---|
401 em toda chamada | Token ausente/rotacionado | Confira o prefixo Authorization: Bearer (sem Basic, sem aspas) |
403 com insufficient_scope | O token é válido mas não tem o escopo da rota | Emita um token com o escopo de required_scope; veja o catálogo de erros |
| Busca vazia logo após um write | Embedding ainda pendente | Faça polling de embed_state; a perna densa precisa de synced |
| Write funciona, a busca nunca acha | Hash do conteúdo já indexado em outro lugar | Dedup cross-collection é por design; mude o conteúdo ou aceite a cópia existente |
| Zero linhas numa consulta que você sabe que bate | O token pertence a outro workspace (o tenant vem da credencial) | Use um token criado no workspace onde o documento foi escrito |
200 mas o score parece baixo numa correspondência exata | Correspondências de string exata ranqueiam pelo pipeline completo, não por igualdade de string | Para identificadores e literais use memory_grep (MCP) ou modo keyword, não ranking semântico |
400 num body >1 MB | Teto rígido no content | Divida o documento; path é sua chave de paginação |