A memória do seu negócio, via API.
Gilgal recebe conteúdo cru de qualquer fonte, organiza sozinho, e devolve fatos carimbados com a fonte citada. Esta referência cobre a API REST, o protocolo MCP para conectar qualquer agente de IA, e o contrato de extração que mantém os fatos confiáveis.
Introdução
O que o Gilgal é, em termos simples, e o modelo mental que você precisa antes de tocar na API.
Gilgal é a memória do seu negócio, via API. Você joga conteúdo cru de qualquer fonte — transcrição de call, mensagem de grupo, e-mail, planilha — e ele guarda. Depois você pergunta em português e recebe a resposta com a fonte citada e um grau de certeza.
O ciclo é sempre o mesmo, e a API o espelha em três verbos: você ingere, o Gilgal organiza, e você pergunta. Você não precisa etiquetar, titular nem estruturar nada à mão. Cada pedaço do que você manda vira um fato ou uma hipótese, ligado às pessoas e aos assuntos, com um carimbo de quando virou verdade e de onde veio.
Início rápido
Do zero ao primeiro fato carimbado em quatro passos. Tudo que você precisa é a chave do bot de um cérebro.
Crie um cérebro e pegue a chave
Cada cérebro é um espaço de memória isolado. Crie um pelo painel e copie a
chave do bot. Ela já vem escopada às áreas e ao nível de
sigilo que você liberou — toda leitura é filtrada por esse escopo.
Mande a primeira informação
Um POST /v1/ingest com o conteúdo cru. Não precisa
formatar nem estruturar: jogue o texto da call, o e-mail, o que for.
curl https://app.gilgal.pro/v1/ingest \
-H "Authorization: Bearer glg_live_8x2k...e1" \
-H "Content-Type: application/json" \
-d '{
"source": "call_vendas",
"content": "Fechamos com a Acme por R$ 2.500/mês. A Maria aprovou.",
"occurred_at": "2026-06-12T14:03:00Z"
}' const res = await fetch("https://app.gilgal.pro/v1/ingest", {
method: "POST",
headers: {
authorization: "Bearer glg_live_8x2k...e1",
"content-type": "application/json",
},
body: JSON.stringify({
source: "call_vendas",
content: "Fechamos com a Acme por R$ 2.500/mês. A Maria aprovou.",
occurred_at: "2026-06-12T14:03:00Z",
}),
});
const data = await res.json(); import requests
res = requests.post(
"https://app.gilgal.pro/v1/ingest",
headers={
"Authorization": "Bearer glg_live_8x2k...e1",
"Content-Type": "application/json",
},
json={
"source": "call_vendas",
"content": "Fechamos com a Acme por R$ 2.500/mês. A Maria aprovou.",
"occurred_at": "2026-06-12T14:03:00Z",
},
)
data = res.json() Deixe organizar
O Gilgal classifica, liga às pessoas e áreas, e decide o que vira fato. É
assíncrono: você acompanha pelo webhook ingest.organized
ou simplesmente pergunta depois.
Pergunte em português
Um POST /v1/ask com a pergunta em linguagem natural. A
resposta sintetiza as fontes e devolve cada fato com o selo — sempre com a fonte
citada.
curl https://app.gilgal.pro/v1/ask \
-H "Authorization: Bearer glg_live_8x2k...e1" \
-H "Content-Type: application/json" \
-d '{ "question": "Qual o preço fechado com a Acme?" }' const res = await fetch("https://app.gilgal.pro/v1/ask", {
method: "POST",
headers: {
authorization: "Bearer glg_live_8x2k...e1",
"content-type": "application/json",
},
body: JSON.stringify({ question: "Qual o preço fechado com a Acme?" }),
});
const data = await res.json(); import requests
res = requests.post(
"https://app.gilgal.pro/v1/ask",
headers={
"Authorization": "Bearer glg_live_8x2k...e1",
"Content-Type": "application/json",
},
json={"question": "Qual o preço fechado com a Acme?"},
)
data = res.json() Conceitos
Cinco objetos atravessam a API inteira. Entenda eles uma vez e o resto se explica.
A unidade de isolamento. Toda chave, fato, área e fonte vive dentro de um
cérebro. Uma empresa pode ter vários — um por cliente, um por
departamento, como fizer sentido. A chave do bot de
um cérebro nunca enxerga outro: cada cérebro é um mundo fechado.
O objeto central. Todo trecho que entra recebe um selo, e a API nunca devolve um fato sem ele. É o que impede a alucinação: uma hipótese jamais é apresentada como se fosse fato.
0.6 normalmente entra como hipótese, não como fato.
occurred_at). Todo fato é citável.
null = ainda vale. Um
fato substituído vira archived e aponta o sucessor
em supersedes.
O assunto onde a memória é guardada — vendas,
suporte, financeiro. Um fato
pode pertencer a mais de uma. O escopo da chave do bot é definido por área
mais nível máximo de sigilo: é assim que você diz o que cada bot pode ler.
Uma fonte é um canal de entrada — uma call de vendas, um grupo de WhatsApp, uma planilha. Cada fonte carrega uma receita: o contrato que diz o que extrair daquele tipo de conteúdo e o que conta como fato. É a peça que mantém os fatos estruturados, detalhada na seção Fontes e receitas.
Arquitetura do Gilgal
Por dentro do cérebro: a esteira que transforma texto cru em fatos datados, e por que o caminho de ler é barato enquanto o de aprender mora nos bastidores.
O Gilgal não é um RAG genérico. Um RAG comum joga tudo num balde de vetores e devolve "o trecho mais parecido". O Gilgal entende o conteúdo: ele destila fatos estruturados — com número, unidade, período, validade no tempo e a entidade dona —, versiona a verdade sem nunca sobrescrever, e devolve cada trecho com um selo que diz o que aquilo é, de onde veio, quando valeu e quanto confiar.
Por trás do verbo organiza roda uma esteira. Ela vive em duas faixas: o que é barato e instantâneo acontece na hora, enquanto você espera; o que é caro — a única IA do caminho de escrita — roda em segundo plano e te avisa quando termina. Você nunca fica travado esperando o cérebro pensar.
valid_from e o trecho literal de onde tirou. Cada etapa da esteira se apoia em peças nomeadas. Juntas, elas são o que separa um motor de memória de uma busca genérica.
valid_from /
valid_to) e quando o cérebro soube. É o que
permite a pergunta as_of: "o que era verdade naquela
data?".
valid_until, e o novo aponta
supersedes. Nada se apaga. Vale insistir num ponto, porque é o coração do "nunca chuta": o selo não é gerado pela IA. Ele é montado por código a partir dos campos que o fato já tem. Por isso custa zero, não adiciona latência e nunca contradiz o dado — é uma janela fiel sobre a memória, não um palpite sobre ela.
{
"trecho": "Fechamos o plano em R$ 2.500/mês.",
"selo": {
"status": "fact",
"confidence": 0.92,
"valid_from": "2026-06-01",
"source": { "tipo": "call_vendas", "cite": "call_2026-06-01#12" },
"via": "vec"
}
} Quatro diferenciais saem de graça desse desenho — e nenhum deles é enfeite de marketing.
- Versiona, não sobrescreve. A verdade muda (um preço vai de 3k a 30k) e o Gilgal guarda a evolução inteira, com a data de cada versão. Pergunte "o que era verdade em abril?" e ele responde. Um RAG comum só conhece o agora e perde o passado.
- Anti-alucinação por construção. Só vira fato o que casa com o contrato da fonte e tem prova (o trecho literal). Toda resposta carrega fonte, data e confiança; uma hipótese jamais aparece como fato. E o selo que carimba isso é determinístico — não sai do caminho rápido.
- Governança por construção, não por política. O sigilo é estrutural: dupla trava, falha fechado, default secreto pro recém-chegado, e a resposta conta o que escondeu em vez de fingir completude. Não é um filtro de tela que dá pra burlar.
- Recuperação híbrida de verdade. Não é "só busca vetorial". São três sinais — significado, palavra exata e vizinhança no grafo — fundidos e reordenados por precisão, tudo determinístico, em milissegundos.
E porque a leitura é livre de IA e barata, o cérebro pluga em qualquer
agente — via MCP ou pela app.gilgal.pro/v1
(Bearer glg_) — como uma camada de memória que
dá pra consultar a cada turno sem pesar na conta.
Casos de uso
Quatro histórias reais de quem joga conteúdo cru e pergunta depois. Em cada uma: o problema, como o Gilgal resolve, o exemplo copiável e o que volta.
Copiloto de vendas
Problema. O preço fechado com um cliente ficou na transcrição da última call, e seu agente de vendas não tem como lembrar disso na hora.
Como o Gilgal resolve. A call já foi ingerida e virou fato carimbado. O agente pergunta em português e recebe o preço com a fonte citada — qual call, em que momento — sem você indexar nada à mão.
curl https://app.gilgal.pro/v1/ask \
-H "Authorization: Bearer glg_live_8x2k...e1" \
-H "Content-Type: application/json" \
-d '{ "question": "Qual o preço fechado com a Acme e quem aprovou?" }' const res = await fetch("https://app.gilgal.pro/v1/ask", {
method: "POST",
headers: {
authorization: "Bearer glg_live_8x2k...e1",
"content-type": "application/json",
},
body: JSON.stringify({ question: "Qual o preço fechado com a Acme e quem aprovou?" }),
});
const data = await res.json(); import requests
res = requests.post(
"https://app.gilgal.pro/v1/ask",
headers={
"Authorization": "Bearer glg_live_8x2k...e1",
"Content-Type": "application/json",
},
json={"question": "Qual o preço fechado com a Acme e quem aprovou?"},
)
data = res.json() {
"answer": "Fechou em R$ 2.500/mês; a Maria aprovou na call de 12/jun.",
"facts": [
{
"text": "Preço fechado com a Acme: R$ 2.500/mês",
"status": "fact",
"confidence": 0.94,
"source": { "type": "call_vendas", "ref": "call-8821",
"occurred_at": "2026-06-12T14:03:00Z" },
"area": ["vendas"],
"valid_from": "2026-06-12T14:03:00Z",
"valid_until": null
}
],
"withheld": { "count": 0 }
} Atendimento com memória
Problema. Um bot de atendimento precisa de contexto do cliente, mas não pode vazar margem, custo ou qualquer coisa de outra área.
Como o Gilgal resolve. A chave do bot já carrega o escopo
(áreas + nível máximo de sigilo). Toda leitura é filtrada no servidor: o que está
fora some da resposta e o campo withheld avisa quantos fatos
ficaram de fora — sem revelar o conteúdo.
curl https://app.gilgal.pro/v1/ask \
-H "Authorization: Bearer glg_live_atend...9c" \
-H "Content-Type: application/json" \
-d '{ "question": "Qual a margem que a gente pratica nesse plano?" }' const res = await fetch("https://app.gilgal.pro/v1/ask", {
method: "POST",
headers: {
authorization: "Bearer glg_live_atend...9c",
"content-type": "application/json",
},
body: JSON.stringify({ question: "Qual a margem que a gente pratica nesse plano?" }),
});
const data = await res.json(); import requests
res = requests.post(
"https://app.gilgal.pro/v1/ask",
headers={
"Authorization": "Bearer glg_live_atend...9c",
"Content-Type": "application/json",
},
json={"question": "Qual a margem que a gente pratica nesse plano?"},
)
data = res.json() {
"answer": "Não tenho fatos liberados pra responder isso aqui.",
"facts": [],
"withheld": { "count": 3, "reason": "out_of_scope" }
} withheld.count deixa claro que existe informação — só não
para esta chave.
Auditoria de decisões
Problema. “Qual era o preço que a gente praticava em maio?” Hoje ele é outro, e a resposta de hoje não serve para auditar a decisão de ontem.
Como o Gilgal resolve. A memória não sobrescreve, ela versiona.
Passe as_of com uma data e receba a memória como era
naquele dia — o preço antigo, antes de virar arquivado.
curl -G https://app.gilgal.pro/v1/facts \
-H "Authorization: Bearer glg_live_8x2k...e1" \
--data-urlencode "area=vendas" \
--data-urlencode "as_of=2026-05-01" const url = new URL("https://app.gilgal.pro/v1/facts");
url.search = new URLSearchParams({
area: "vendas",
as_of: "2026-05-01",
}).toString();
const res = await fetch(url, {
headers: { authorization: "Bearer glg_live_8x2k...e1" },
});
const data = await res.json(); import requests
res = requests.get(
"https://app.gilgal.pro/v1/facts",
headers={"Authorization": "Bearer glg_live_8x2k...e1"},
params={"area": "vendas", "as_of": "2026-05-01"},
)
data = res.json() {
"facts": [
{
"text": "Preço do plano Pro: R$ 12.000",
"status": "fact",
"valid_from": "2026-04-10",
"valid_until": "2026-05-20",
"supersedes": null
}
]
} valid_from e valid_until provando
a janela em que o fato valeu.
Integração de novo funcionário
Problema. Quem entra precisa do que é relevante para a função — e nada além disso. Dar acesso a tudo é risco; dar acesso a nada trava o trabalho.
Como o Gilgal resolve. Crie uma chave restrita à área da pessoa. O mesmo cérebro, a mesma pergunta — a resposta só traz o que aquele escopo alcança. Conforme a pessoa cresce, você amplia a chave.
curl https://app.gilgal.pro/v1/ask \
-H "Authorization: Bearer glg_live_onb...4f" \
-H "Content-Type: application/json" \
-d '{ "question": "Como a gente costuma responder objeção de preço?" }' const res = await fetch("https://app.gilgal.pro/v1/ask", {
method: "POST",
headers: {
authorization: "Bearer glg_live_onb...4f",
"content-type": "application/json",
},
body: JSON.stringify({ question: "Como a gente costuma responder objeção de preço?" }),
});
const data = await res.json(); import requests
res = requests.post(
"https://app.gilgal.pro/v1/ask",
headers={
"Authorization": "Bearer glg_live_onb...4f",
"Content-Type": "application/json",
},
json={"question": "Como a gente costuma responder objeção de preço?"},
)
data = res.json() Fluxos
Como as peças se encaixam, em três desenhos: o loop central, a leitura que falha fechado, e a linha do tempo que nunca apaga o passado.
Tudo no Gilgal gira em torno de três verbos. Você ingere conteúdo cru, ele organiza sozinho (cada trecho vira fato ou hipótese, ligado a pessoas, áreas e uma fonte citável), e você pergunta em português. A resposta volta com a fonte carimbada — e cada pergunta nova reaproveita tudo que já entrou.
A chave do bot já carrega o escopo: as áreas que pode ler e o teto de sigilo. Toda leitura é filtrada no servidor por esse escopo. Se um fato está acima do que a chave alcança, ele nunca aparece — e a resposta ainda diz quantos ficaram de fora, em vez de fingir que está completa.
vendas, sigilo
internal → entra na resposta. financeiro ou marcado
secret → fica de fora, contado em
withheld. {
"answer": "O preço atual da Acme é R$ 2.500/mês.",
"facts": [ /* ... só o que a chave alcança ... */ ],
"withheld": { "count": 3, "reason": "fora do seu acesso" }
}
A memória do Gilgal não sobrescreve — ela versiona. Quando um fato novo
contradiz um antigo, o antigo não some: ele vira archived, ganha um
valid_until, e o novo aponta para ele em supersedes.
Com as_of você revisita qualquer data e vê o que era verdade naquele
momento.
GET /v1/facts?as_of=2026-04-01 devolve o registro como ele era — o
preço de R$ 12.000, ainda vivo, antes de virar arquivado. {
"event": "fact.superseded",
"archived": {
"id": "fact_7a1j04",
"text": "Preço Acme: R$ 12.000/mês",
"valid_until": "2026-05-30"
},
"successor": {
"id": "fact_8x2k01",
"text": "Preço Acme: R$ 2.500/mês",
"supersedes": "fact_7a1j04"
}
} Autenticação
Toda chamada usa a chave do bot do cérebro, no header Authorization. A chave já carrega o escopo — a API nunca devolve mais do que ela pode ver.
curl https://app.gilgal.pro/v1/ask \
-H "Authorization: Bearer glg_live_8x2k9d2m...e1" \
-H "Content-Type: application/json" \
-d '{ "question": "Qual o preço fechado com a Acme?" }' const res = await fetch("https://app.gilgal.pro/v1/ask", {
method: "POST",
headers: {
authorization: "Bearer glg_live_8x2k9d2m...e1",
"content-type": "application/json",
},
body: JSON.stringify({ question: "Qual o preço fechado com a Acme?" }),
}); import requests
res = requests.post(
"https://app.gilgal.pro/v1/ask",
headers={
"Authorization": "Bearer glg_live_8x2k9d2m...e1",
"Content-Type": "application/json",
},
json={"question": "Qual o preço fechado com a Acme?"},
)
Cada chave nasce com um conjunto de áreas e um teto de sigilo. Toda leitura
é filtrada por esse escopo do lado do servidor: se a chave não alcança o
financeiro, uma pergunta sobre preço simplesmente não
enxerga aqueles fatos. É menor privilégio por padrão — a chave só vê o que
você liberou.
| Campo da chave | Descrição |
|---|---|
| areas string[] | As áreas que a chave pode ler. ["*"] = todas (use com cautela). |
| max_sensitivity enum | O teto de sigilo: open · internal · confidential · secret. Nada acima é retornado. |
| can_ingest boolean | Se a chave pode escrever (/v1/ingest) ou só ler. |
secret por padrão. Ele só fica visível depois que
alguém amplia o acesso de propósito. Não é bug: é o princípio de nunca vazar
nada por engano.
Ingestão
Manda conteúdo cru pro cérebro. Você não estrutura nada: a receita da fonte cuida disso.
| Parâmetro | Descrição |
|---|---|
| source string obrigatório | O slug da fonte que define a receita de extração (ex.: call_vendas). É ele que decide o que vira fato. |
| content string obrigatório | O conteúdo cru: texto, transcrição, corpo de e-mail. Joga do jeito que está, sem formatar nada. |
| occurred_at datetime opcional | Quando o conteúdo aconteceu (ISO 8601). Define a posição na linha do tempo. Padrão: agora. |
| participants string[] opcional | Quem estava envolvido, pra ajudar a ligar os fatos. O Gilgal também infere do próprio conteúdo. |
| sensitivity enum opcional | Força um nível de sigilo de entrada. Se omitir, a receita decide; sem receita, entra como secret. |
curl https://app.gilgal.pro/v1/ingest \
-H "Authorization: Bearer glg_live_8x2k...e1" \
-H "Content-Type: application/json" \
-d '{
"source": "call_vendas",
"content": "Fechamos com a Acme por R$ 2.500/mês. A Maria aprovou.",
"occurred_at": "2026-06-12T14:03:00Z",
"sensitivity": "confidential"
}' const res = await fetch("https://app.gilgal.pro/v1/ingest", {
method: "POST",
headers: {
authorization: "Bearer glg_live_8x2k...e1",
"content-type": "application/json",
},
body: JSON.stringify({
source: "call_vendas",
content: "Fechamos com a Acme por R$ 2.500/mês. A Maria aprovou.",
occurred_at: "2026-06-12T14:03:00Z",
sensitivity: "confidential",
}),
});
const data = await res.json(); import requests
res = requests.post(
"https://app.gilgal.pro/v1/ingest",
headers={
"Authorization": "Bearer glg_live_8x2k...e1",
"Content-Type": "application/json",
},
json={
"source": "call_vendas",
"content": "Fechamos com a Acme por R$ 2.500/mês. A Maria aprovou.",
"occurred_at": "2026-06-12T14:03:00Z",
"sensitivity": "confidential",
},
)
data = res.json()
A ingestão é assíncrona. A API confirma o recebimento na hora com um 202 e um batch_id; a organização acontece logo depois e dispara o
webhook ingest.organized.
{
"batch_id": "ing_2026q2_7a1j9",
"status": "organizing",
"source": "call_vendas",
"received_at": "2026-06-12T14:03:11Z"
}
Se você não usa webhook, consulte o estado do batch com o batch_id que
veio no 202. O status caminha por organizing → indexed (já dá pra buscar) → organized (terminal),
ou failed. Em organized, result.facts
traz quantas partes entraram. O batch só é visível pra quem é do mesmo cérebro da chave.
{
"batch_id": "ing_2026q2_7a1j9",
"status": "organized",
"progress": 1,
"result": { "facts": 3 }
}
O /ingest é a porta crua. Pra canais conhecidos existe a família
POST /v1/ingestors/<slug> — webhooks que entendem o formato da
ferramenta e preparam o conteúdo antes do funil (com janela de conversa pra chats e
fatos determinísticos pra planilhas). Veja Integrações prontas.
Perguntar
A leitura principal. Você pergunta em português e recebe uma síntese mais os fatos que a sustentam, cada um carimbado com a fonte.
Mande a pergunta em linguagem natural no campo question. A leitura
sempre passa pelo escopo da sua chave — áreas e nível de sigilo — antes de
voltar. Você nunca vê o que a chave não pode ver.
curl https://app.gilgal.pro/v1/ask \
-H "Authorization: Bearer glg_live_8x2k...e1" \
-H "Content-Type: application/json" \
-d '{
"question": "Qual o preço fechado com a Acme?"
}' const res = await fetch("https://app.gilgal.pro/v1/ask", {
method: "POST",
headers: {
authorization: "Bearer glg_live_8x2k...e1",
"content-type": "application/json",
},
body: JSON.stringify({
question: "Qual o preço fechado com a Acme?",
}),
});
const data = await res.json(); import requests
res = requests.post(
"https://app.gilgal.pro/v1/ask",
headers={
"Authorization": "Bearer glg_live_8x2k...e1",
"Content-Type": "application/json",
},
json={
"question": "Qual o preço fechado com a Acme?",
},
)
data = res.json()
A resposta traz três coisas: a answer (a síntese pronta pra ler),
a lista facts (cada fato com o selo completo que o sustenta) e
withheld (quantos fatos ficaram de fora do seu acesso).
{
"answer": "O preço fechado com a Acme é R$ 2.500/mês, aprovado pela Maria em 12/jun.",
"facts": [
{
"id": "fact_8x2k01",
"status": "fact",
"text": "Preço fechado com a Acme: R$ 2.500/mês.",
"confidence": 0.92,
"sensitivity": "confidential",
"area": ["vendas"],
"source": {
"type": "call_vendas",
"ref": "call_2026-06-12",
"occurred_at": "2026-06-12T14:03:00Z"
},
"valid_from": "2026-06-12",
"valid_until": null,
"supersedes": "fact_7a1j04"
}
],
"withheld": { "count": 3, "reason": "fora do seu acesso" }
} withheld é honestidade, não erro. Quando o escopo da
chave deixa fatos de fora, a API conta quantos e por quê, em vez de fingir que a resposta é
completa. É o mesmo “3 fontes ficaram de fora” que aparece no produto.
/v1/ask responde 402
com current_usd e limit_usd — e volta ao
normal à meia-noite UTC. As leituras de /v1/facts não gastam IA e seguem
livres.
Fatos
Acesso direto aos fatos, sem síntese. Útil pra alimentar interfaces, auditar ou exportar.
| Parâmetro | Descrição |
|---|---|
| area string opcional | Filtra por área (ex.: ?area=vendas). |
| status enum opcional | fact · archived. Padrão: fact. Um fato cujo valid_until já passou (relativo a as_of, ou a hoje) vem como archived. hypothesis ainda não é exposto por esta rota (roadmap). |
| as_of date opcional | Estado da memória naquela data. Revisita o passado: o que era verdade em 01/mai. |
| min_confidence number opcional | Piso de certeza (0–1). Útil pra filtrar ruído. |
| limit number opcional | Itens por página. Padrão 50, máx 200. Use cursor pra paginar — ele só aparece quando há de fato mais itens no seu escopo. |
curl -G https://app.gilgal.pro/v1/facts \
-H "Authorization: Bearer glg_live_8x2k...e1" \
--data-urlencode "area=vendas" \
--data-urlencode "status=fact" \
--data-urlencode "as_of=2026-05-01" \
--data-urlencode "min_confidence=0.7" \
--data-urlencode "limit=50" const url = new URL("https://app.gilgal.pro/v1/facts");
url.search = new URLSearchParams({
area: "vendas",
status: "fact",
as_of: "2026-05-01",
min_confidence: "0.7",
limit: "50",
}).toString();
const res = await fetch(url, {
headers: { authorization: "Bearer glg_live_8x2k...e1" },
});
const data = await res.json(); import requests
res = requests.get(
"https://app.gilgal.pro/v1/facts",
headers={"Authorization": "Bearer glg_live_8x2k...e1"},
params={
"area": "vendas",
"status": "fact",
"as_of": "2026-05-01",
"min_confidence": 0.7,
"limit": 50,
},
)
data = res.json() as_of é o “mostra o que mudou”. Consultar
fatos numa data passada devolve o registro como ele era — incluindo o preço antigo,
antes de virar arquivado. A memória do Gilgal não sobrescreve: ela versiona.
truncated: true — sinal honesto de que pode haver fatos além
do que foi varrido. Refine por area/as_of
pra estreitar o universo.
Fontes e receitas
A peça que mantém os fatos confiáveis. Cada fonte declara o que extrair; o que não casa não vira fato.
Jogar texto cru num balde genérico é exatamente o que causa alucinação: o modelo inventa estrutura onde não há. A receita resolve isso virando um contrato. Uma call de vendas extrai preço, decisão e próximo passo; uma planilha financeira extrai valores e datas. O que a receita reconhece vira fato; o resto vira hipótese e espera revisão.
{
"source": "call_vendas",
"area": ["vendas"],
"default_sensitivity": "confidential",
"extract": [
{ "field": "preco_falado", "as": "fact", "require": ["value", "date"] },
{ "field": "proximo_passo", "as": "fact" },
{ "field": "objecao", "as": "hypothesis" }
],
"fallback": "hypothesis"
} ["value","date"] = só vira
fato se tiver valor e data; senão cai pra hipótese.
hypothesis, nunca fact.
require. Todo o
resto entra como hipótese e fica na fila de revisão. É o contrato que separa o
Gilgal de uma busca genérica.
| Slug | O que ingere |
|---|---|
| call_vendas | Transcrições de call de vendas. Extrai preço, decisão e próximo passo. |
| whatsapp_grupo | Conversas de grupo. Resolve quem disse o quê por participante. |
| email_comercial | Threads de e-mail. Extrai compromissos, prazos e valores citados. |
| planilha_xls | Planilhas financeiras. Extrai valores e datas como fatos estruturados. |
| teams_call · slack | Reuniões e canais. Mesma receita de call, adaptada ao formato. |
| documento | PDFs e contratos. Extrai cláusulas, partes e datas de vigência. |
MCP: conecte qualquer IA
O Gilgal expõe um servidor MCP (Model Context Protocol). Qualquer agente que fala MCP — o Claude, o seu próprio agente, o que for — ganha a memória como ferramenta, já respeitando o escopo da chave.
Adicione o servidor à config do seu cliente MCP. A chave do bot define o que o agente enxerga: ele nunca recebe um fato fora do escopo, mesmo que peça.
{
"mcpServers": {
"gilgal": {
"command": "npx",
"args": ["-y", "@gilgal/mcp"],
"env": {
"GILGAL_TOKEN": "glg_live_8x2k...e1",
"GILGAL_API_URL": "https://seu-gilgal/v1"
}
}
}
} /ask.
can_ingest. É assim que o
agente alimenta a memória.
batch_id — o agente sabe
quando o que ele gravou virou memória.
Integrações prontas
Além do /ingest cru, o Gilgal tem ingestores por canal — cada um com um webhook público que entende o formato da ferramenta e prepara o conteúdo antes do funil (dedupe + fila + extração).
GET /v1/ingestors lista os disponíveis. Re-entregar o mesmo
evento não duplica (dedupe por referência estável). Ferramenta que não
deixa configurar header? Use ?token=glg_live_... na URL.
texto— webhook genérico pra qualquer automação (e o template pra copiar).evolution-whatsapp— WhatsApp self-hosted (Evolution API, evento MESSAGES_UPSERT).chatwoot— o inbox omnichannel: WhatsApp, Instagram DM, Telegram, e-mail e livechat numa integração só (evento message_created).chat— QUALQUER canal de conversa (ManyChat, Telegram, Crisp…): a automação só mapeia os campos.notetaker— transcrições de reunião (Fireflies, tl;dv, MeetGeek…).formulario— leads e submissões (Google Forms, Typeform, site).planilha— tabela → fatos carimbados NA HORA, sem IA (preços, catálogo, comissões).
curl -X POST "https://seu-gilgal/v1/ingestors/texto" \
-H "Authorization: Bearer glg_live_8x2k...e1" \
-H "Content-Type: application/json" \
-d '{ "title": "Ata da reunião", "text": "Decidimos que...", "occurred_at": "2026-07-01" }'
"Consegue remarcar?" sem o "claro, sexta 15h" que vem depois não vira fato. Por isso
todo canal de chat usa a janela de conversa: cada mensagem entra num
buffer por chat (202 buffered) e a conversa INTEIRA vira uma
memória só quando o chat silencia (~30 min) ou junta ~100 mensagens. A extração enxerga
pergunta + resposta + decisão juntas — e o custo cai ~10-20× num WhatsApp movimentado.
{ "canal": "instagram", "chat_id": "dm-8817",
"chat_label": "Instagram — @beatriz",
"quem": "Beatriz", "texto": "Vocês têm horário no sábado?" } n8n — nó nativo n8n-nodes-gilgal (Settings →
Community Nodes): ingestão (texto, chat, reunião, formulário, planilha, payload cru) +
memória (perguntar, buscar fatos). Zapier — app oficial com 6 ações
(distribuída por link privado) ou, hoje mesmo, a ação Webhooks by Zapier apontando
pros ingestores acima. Cases prontos de Zaps no repositório
(ZAPIER.md).
Em Ajustes → GitHub do cérebro (repo privado + PAT fine-grained com contents: read/write), a memória vira um repositório organizado pra gente — um commit legível por sincronização (~2 min), espelho fiel (o que sai do cérebro some do repo):
README.md ← painel: o que o cérebro sabe, dossiês, últimas memórias
conhecimento/ ← um dossiê por pessoa/empresa/assunto
reunioes/2026/2026-08-03 — Reunião de equipe.md
conversas/2026/2026-08-01 — WhatsApp 4799992222.md
documentos/2026/2026-08-01 — Tabela de preços (agosto).md
anotacoes/2026/…
entrada/ ← SUA pasta: solte .md/.txt/.csv/.pdf e o Gilgal ingere
A entrada/ é a sua caixa de entrada: quando o arquivo
some de lá, virou memória; se ficou, ainda está processando (ou deu
erro). Subpastas classificam: entrada/reunioes/ata.md entra
como reunião.
Google Drive for Desktop / OneDrive / Dropbox sincronizando no disco +
gilgal pasta --dir ~/GoogleDrive/Gilgal: todo
pdf/md/txt/csv novo ou alterado entra na fila. Rodar de novo não re-ingere.
Webhooks
A ingestão é assíncrona, então o Gilgal avisa o seu app por HTTP quando algo é organizado ou muda de estado. Você registra uma URL com a sua chave, recebe um secret, e valida a assinatura de cada entrega.
A URL precisa ser https:// e pública — o Gilgal recusa IP privado, loopback e
link-local (anti-SSRF). O secret é mostrado uma única vez:
guarde-o, é com ele que você verifica a assinatura de cada entrega.
curl -X POST https://app.gilgal.pro/v1/webhooks \
-H "Authorization: Bearer glg_live_8x2k...e1" \
-H "Content-Type: application/json" \
-d '{
"url": "https://seu-app.com/webhooks/gilgal",
"events": ["ingest.organized", "fact.superseded"]
}' {
"id": "wh_7a1j9",
"url": "https://seu-app.com/webhooks/gilgal",
"events": ["ingest.organized", "fact.superseded"],
"secret": "whsec_3f8c...e2",
"status": "active"
}
Liste com GET /v1/webhooks (a resposta nunca traz o secret) e remova com
DELETE /v1/webhooks/:id. Os webhooks são por cérebro — a chave só
enxerga os do próprio.
| Evento | Quando dispara |
|---|---|
| ingest.organized | Um lote terminou de ser organizado. Traz as contagens (fatos criados, itens que foram pra revisão). |
| review.pending | Trechos não casaram com a receita e entraram na fila de revisão como hipótese, esperando alguém. |
| fact.superseded | Um fato foi substituído por um mais novo (virou archived). Traz só o id e a data — nunca o valor. |
| access.denied | Uma leitura foi 100% barrada pelo escopo da chave (ou uma escrita sem permissão). Só em negação TOTAL — nunca quando parte do resultado é mostrada. |
withheld da resposta, não um alerta. O webhook
só sai quando uma leitura volta 100% vazia por barreira de escopo (ou numa escrita sem
permissão), e no máximo um por chave por minuto — pra não virar ruído nem vazar a existência do
que ficou escondido.
{
"event": "ingest.organized",
"batch_id": "ing_2026q2_7a1j9",
"result": { "facts": 4, "pending_review": 1 },
"at": "2026-06-12T14:03:48Z"
}
Os payloads são mínimos — contagens, ids e datas, nunca o valor de um fato.
Quer o detalhe? Chame /v1/facts com a sua chave.
Toda entrega traz o header X-Gilgal-Signature = HMAC-SHA256 do corpo
cru, com o seu secret. Confira antes de confiar no payload:
import crypto from "node:crypto";
// Em cada POST que você receber do Gilgal:
const esperada = crypto
.createHmac("sha256", SEU_SECRET) // o secret mostrado no registro
.update(rawBody) // o CORPO CRU, antes de parsear o JSON
.digest("hex");
if (esperada !== req.headers["x-gilgal-signature"]) {
return res.status(401).end(); // não é do Gilgal — descarte
} 2xx pra confirmar; 5xx/timeout são re-tentados,
4xx não. Depois de várias falhas seguidas o webhook é desativado.
Erros e limites
Códigos HTTP padrão e o que cada um significa no contexto do Gilgal, mais os limites de cada chave.
/v1/ask (que sintetiza) é barrado; a resposta traz current_usd e limit_usd. Reseta à meia-noite UTC. source que você mandou não tem receita configurada neste cérebro. Retry-After e tente de novo. | Endpoint | Limite |
|---|---|
| /v1/ask | 60 chamadas por minuto. A resposta é sintetizada, então pesa mais — use com calma. |
| /v1/ingest | 600 chamadas por minuto. O campo content aceita até 256 KB por chamada. |
| /v1/facts | 300 chamadas por minuto. Para listas grandes, pagine com cursor em vez de subir o limit. |
open · internal · confidential · secret,
que o produto exibe como Aberto · Interno · Sigiloso · Secreto.
São os mesmos quatro níveis, mapeados 1:1.