Lampson como motor
API HTTP
Cada projeto (workspace) do Lampson expõe uma API para seus apps, seus bots e outros agentes:
https://seu-lampson/w/<workspace>/v1/…
Sem URL pública, a base é http://127.0.0.1:8080/w/<workspace>/v1 — só a partir deste computador. Para usar de fora: lampson --domain ou um túnel.
API keys§
A API pede sempre uma key, também a partir do mesmo computador.
lampson key add --agent tienda --name "bot do whatsapp"
lampson key add --agent tienda,soporte --rate 60 --callback https://hooks.mi-app.com/
lampson key list
lampson key remove k6KJgJHpu
Ou pela web: API no painel esquerdo → + crear una API key (“+ criar uma API key”).
- A key é mostrada uma única vez, com as URLs da API e do MCP prontas para copiar. O Lampson guarda só o hash dela.
--agent: os agentes que ela pode usar (sem opção, todos).--rate N: pedidos por minuto (padrão 120;0= sem limite). Passado o limite, responde429comRetry-After.--callback URL: as únicas URLs para as quais o Lampson mandará callbacks com esta key: mesmo esquema, host e porta, e o caminho como pasta (https://app.com/hookspermite/hooks/…, nãoapp.com.evil.netnem/hooks-x). Sem essa opção, a key não pode pedir callbacks. As keys criadas antes do Lampson 0.5.1 chegam a qualquer nome de host público, elampson key listas marca para que você as substitua.- Uma key da API só abre
/v1: nunca a interface web, o terminal nem o chat.
Um workspace com keys não é desligado por inatividade: senão, a próxima mensagem do seu bot o encontraria desligado.
Enviar uma mensagem§
curl -X POST https://seu-lampson/w/tienda/v1/messages \
-H "Authorization: Bearer lk_…" -H "Content-Type: application/json" \
-d '{"to": "tienda", "thread": "whatsapp:+5491122334455", "text": "vocês têm pão integral?"}'
{"agent": "tienda", "thread": "whatsapp:+5491122334455", "session": "20261016-132332-8546",
"text": "Olá! Sim, temos pão integral de fermentação natural a $3.200.", "steps": 2,
"usage": {"input": 1453, "output": 148, "cached": 1024}, "stopped": "done",
"batch": ["m59429972irl8"], "lead": "m59429972irl8"}
O body é um envelope:
| campo | |
|---|---|
text | a mensagem (obrigatório) |
to | o agente (por padrão, o do workspace) |
thread | quem/o que é esta conversa: mesmo thread = mesma conversa. Cada key tem as suas: outro app com o mesmo thread começa outra |
session | ou uma sessão conhecida, desta mesma key (a de outra key dá 404) |
images | [{"media_type": "image/jpeg", "data": "<base64>"}] — os modelos com visão as veem |
from, meta | livres: viajam com a mensagem (ids do seu sistema, nome do cliente) |
sent_at | quando o cliente escreveu (unix): ordena uma rajada que chegou fora de ordem |
callback | veja abaixo |
Erros: 400 (envelope inválido), 401 (sem key ou key inválida), 403 (agente fora da key, ou callback não permitido), 404 (agente inexistente), 429 (limite).
Três formas de receber a resposta§
- JSON —
POST /v1/messages: o request espera o agente e devolve o resultado. - Streaming —
POST /v1/messages/stream: Server-Sent Events com cada passo (session,assistant,tool_call…,done), comolampson run --json. - Callback —
POST /v1/messagescom"callback": "https://…": responde202 {"job": "m…", "status": "queued"}na hora e, quando o agente termina, o Lampson faz um POST para a sua URL. É o que os webhooks do WhatsApp e companhia precisam, porque exigem uma resposta rápida.
O callback leva {job, jobs, batch, status, agent, thread, session, text, steps, usage, stopped, meta}. Ele vai assinado com o segredo da key que o pediu, que o lampson key add mostra uma única vez junto com a key: X-Lampson-Signature: sha256=<HMAC-SHA256 do body>, e X-Lampson-Key diz qual key é. Assim, outro app que use o mesmo Lampson não consegue assinar um callback falso para o seu. As keys criadas antes do Lampson 0.5.1 assinam com LAMPSON_WEBHOOK_SECRET, como antes. Verifique com o SDK ou:
import hmac, hashlib
ok = hmac.compare_digest("sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest(), signature)
GET /v1/jobs/<id> devolve o estado de uma mensagem enviada com callback.
A caixa de entrada§
Cada conversa (agente + thread) tem a sua caixa de entrada. Isso já vem resolvido, não precisa configurar:
- Nunca dois turnos ao mesmo tempo na mesma conversa. Clientes diferentes rodam, sim, em paralelo.
- As rajadas se juntam. O turno começa após 3 segundos sem mensagens novas (ou 15 desde a primeira): «oi» / «quanto custa o pão sem glúten?» / «tem em estoque?» vão em um turno e recebem uma resposta — a mesma nos três requests, com
batch(as mensagens do lote) elead(a primeira). Com callback sai um POST por lote. - O que chega no meio do turno entra no turno em andamento, antes de o agente responder. Se chega quando o modelo já está escrevendo a resposta, o Lampson a descarta e responde de novo com tudo: nunca sai uma resposta que ignora a última mensagem do cliente.
A espera se ajusta por agente com "buffer": {"quiet_s": 3, "max_s": 15}, ou "buffer": false para responder sem esperar (a fila continua). → Agentes
Objetivos§
Um objetivo é algo que um agente (ou uma equipe) trabalha sozinho até terminar.
curl -X POST https://seu-lampson/w/loja/v1/objectives -H "Authorization: Bearer lk_…" \
-d '{"agent": "cto", "text": "Adicione filtrar por status, com testes; me peça aprovação antes do merge.", "budget_tokens": 400000}'
POST /v1/objectives | criar: {text, agent? | team?, budget_tokens?, round_seconds?} → 201 com o objetivo |
GET /v1/objectives | os que esta key pode ver (os dos seus agentes) |
GET /v1/objectives/<id> | um: status (active, waiting, done, failed, cancelled, paused), progress (último informe), question e question_kind (question ou approval), result, tasks (o quadro), ledger (o registro), spent |
POST /v1/objectives/<id>/reply | responder: {text} a uma pergunta, {approved: true|false, text?} a uma aprovação |
POST /v1/objectives/<id>/cancel | interromper |
Um objetivo waiting não avança nem gasta até você responder.
Outros endpoints§
GET /v1/agents | os agentes que esta key pode usar |
GET /v1/jobs/<id> | estado de uma mensagem com callback |
POST /v1/mcp · /v1/mcp/stream | MCP por HTTP → Lampson como servidor MCP |
GET /v1/openapi.json | o OpenAPI 3.1 desta API |
OpenAPI§
/v1/openapi.json descreve só a API pública — a interface web, o terminal e os webhooks dos canais não aparecem. Use para gerar um cliente na sua linguagem (openapi-generator para Go, Java, C#, PHP…) ou para testar a API na sua ferramenta favorita. Para JavaScript e Python já existe SDK.