Lampson como motor
API HTTP
Cada proyecto (workspace) de Lampson expone una API para tus apps, tus bots y otros agentes:
https://tu-lampson/w/<workspace>/v1/…
Sin URL pública, la base es http://127.0.0.1:8080/w/<workspace>/v1 — solo desde esta PC. Para usarla desde afuera: lampson --domain o un túnel.
API keys§
La API pide siempre una key, también desde la misma PC.
lampson key add --agent tienda --name "bot de whatsapp"
lampson key add --agent tienda,soporte --rate 60 --callback https://hooks.mi-app.com/
lampson key list
lampson key remove k6KJgJHpu
O desde la web: API en el panel izquierdo → + crear una API key.
- La key se muestra una sola vez, con las URLs de la API y del MCP listas para copiar. Lampson guarda solo su hash.
--agent: los agentes que puede usar (sin opción, todos).--rate N: pedidos por minuto (por defecto 120;0= sin límite). Pasado el límite responde429conRetry-After.--callback URL: las únicas URLs a las que Lampson le mandará callbacks con esta key: mismo esquema, host y puerto, y la ruta como carpeta (https://app.com/hooksdeja/hooks/…, noapp.com.evil.netni/hooks-x). Sin esta opción, la key no puede pedir callbacks. Las keys creadas antes de Lampson 0.5.1 llegan a cualquier nombre de host público, ylampson key listlas marca para que las reemplaces.- Una key de la API solo abre
/v1: nunca la interfaz web, la terminal ni el chat.
Un workspace con keys no se apaga por inactividad: si no, el próximo mensaje de tu bot lo encontraría apagado.
Mandar un mensaje§
curl -X POST https://tu-lampson/w/tienda/v1/messages \
-H "Authorization: Bearer lk_…" -H "Content-Type: application/json" \
-d '{"to": "tienda", "thread": "whatsapp:+5491122334455", "text": "¿tienen pan integral?"}'
{"agent": "tienda", "thread": "whatsapp:+5491122334455", "session": "20261016-132332-8546",
"text": "¡Hola! Sí, tenemos pan integral de masa madre a $3.200.", "steps": 2,
"usage": {"input": 1453, "output": 148, "cached": 1024}, "stopped": "done",
"batch": ["m59429972irl8"], "lead": "m59429972irl8"}
El body es un sobre:
| campo | |
|---|---|
text | el mensaje (obligatorio) |
to | el agente (por defecto, el del workspace) |
thread | quién/qué es esta conversación: mismo thread = misma conversación. Cada key tiene las suyas: otra app con el mismo thread empieza otra |
session | o una sesión conocida, de esta misma key (la de otra key da 404) |
images | [{"media_type": "image/jpeg", "data": "<base64>"}] — los modelos con visión las ven |
from, meta | libres: viajan con el mensaje (ids de tu sistema, nombre del cliente) |
sent_at | cuándo escribió el cliente (unix): ordena una ráfaga que llegó desordenada |
callback | ver abajo |
Errores: 400 (sobre inválido), 401 (sin key o key inválida), 403 (agente fuera de la key, o callback no permitido), 404 (agente inexistente), 429 (límite).
Tres formas de recibir la respuesta§
- JSON —
POST /v1/messages: el request espera al agente y devuelve el resultado. - Streaming —
POST /v1/messages/stream: Server-Sent Events con cada paso (session,assistant,tool_call…,done), comolampson run --json. - Callback —
POST /v1/messagescon"callback": "https://…": responde202 {"job": "m…", "status": "queued"}enseguida y, cuando el agente termina, Lampson hace un POST a tu URL. Es lo que necesitan los webhooks de WhatsApp y compañía, que exigen una respuesta rápida.
El callback lleva {job, jobs, batch, status, agent, thread, session, text, steps, usage, stopped, meta}. Va firmado con el secreto de la key que lo pidió, que lampson key add muestra una sola vez junto a la key: X-Lampson-Signature: sha256=<HMAC-SHA256 del body>, y X-Lampson-Key dice qué key es. Así, otra app que use el mismo Lampson no puede firmar un callback falso para la tuya. Las keys creadas antes de Lampson 0.5.1 firman con LAMPSON_WEBHOOK_SECRET, como antes. Verifícalo con el SDK o:
import hmac, hashlib
ok = hmac.compare_digest("sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest(), signature)
GET /v1/jobs/<id> devuelve el estado de un mensaje enviado con callback.
El buzón§
Cada conversación (agente + thread) tiene su buzón. Esto viene resuelto, no hay que configurarlo:
- Nunca dos turnos a la vez sobre la misma conversación. Clientes distintos sí van en paralelo.
- Las ráfagas se juntan. El turno arranca tras 3 segundos sin mensajes nuevos (o a los 15 desde el primero): «hola» / «¿precio del pan sin gluten?» / «¿hay stock?» van en un turno y reciben una respuesta — la misma en los tres requests, con
batch(los mensajes del lote) ylead(el primero). Con callback sale un POST por lote. - Lo que llega a mitad de turno entra al turno en curso, antes de que el agente responda. Si llega mientras el modelo ya estaba escribiendo la respuesta, Lampson la descarta y responde de nuevo con todo: nunca sale una respuesta que ignora lo último que escribió el cliente.
La espera se ajusta por agente con "buffer": {"quiet_s": 3, "max_s": 15}, o "buffer": false para responder sin esperar (la fila sigue). → Agentes
Objetivos§
Un objetivo es algo que un agente (o un equipo) trabaja solo hasta terminarlo.
curl -X POST https://tu-lampson/w/tienda/v1/objectives -H "Authorization: Bearer lk_…" \
-d '{"agent": "cto", "text": "Agregá filtrar por estado, con tests; pedime aprobación antes de mergear.", "budget_tokens": 400000}'
POST /v1/objectives | crear: {text, agent? | team?, budget_tokens?, round_seconds?} → 201 con el objetivo |
GET /v1/objectives | los que esta key puede ver (los de sus agentes) |
GET /v1/objectives/<id> | uno: status (active, waiting, done, failed, cancelled, paused), progress (último informe), question y question_kind (question o approval), result, tasks (su tablero), ledger (su registro), spent |
POST /v1/objectives/<id>/reply | responder: {text} a una pregunta, {approved: true|false, text?} a una aprobación |
POST /v1/objectives/<id>/cancel | cortarlo |
Un objetivo waiting no avanza ni gasta hasta que respondas.
Otros endpoints§
GET /v1/agents | los agentes que esta key puede usar |
GET /v1/jobs/<id> | estado de un mensaje con callback |
POST /v1/mcp · /v1/mcp/stream | MCP por HTTP → Lampson como servidor MCP |
GET /v1/openapi.json | el OpenAPI 3.1 de esta API |
OpenAPI§
/v1/openapi.json describe solo la API pública — la interfaz web, la terminal y los webhooks de los canales no aparecen. Úsalo para generar un cliente en tu lenguaje (openapi-generator para Go, Java, C#, PHP…) o para probar la API desde tu herramienta favorita. Para JavaScript y Python ya hay SDK.