WebSocket API¶
The WebSocket API provides real-time bidirectional communication with engram.
Endpoint: ws://host:8765/ws
Authentication: ws://host:8765/ws?token=<JWT> (token optional when auth disabled)
Connection¶
const ws = new WebSocket("ws://localhost:8765/ws");
ws.onopen = () => {
ws.send(JSON.stringify({ command: "status", payload: {} }));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log(data);
};
Commands¶
All commands follow the format:
remember¶
Store a memory.
{
"command": "remember",
"payload": {
"content": "Switched to PostgreSQL backend",
"memory_type": "decision",
"priority": 9
}
}
recall¶
Search episodic memories.
think¶
LLM reasoning across episodic + semantic memory.
feedback¶
Record positive or negative feedback on a memory.
query¶
Search the semantic knowledge graph.
ingest¶
Extract entities from messages and store memories.
{
"command": "ingest",
"payload": {
"messages": [
{ "role": "user", "content": "We decided to use Redis for caching" }
]
}
}
status¶
Get memory statistics.
Push Events¶
Engram pushes events to all connected clients when memory state changes:
| Event | Trigger |
|---|---|
memory_created |
New memory stored |
memory_updated |
Memory modified (feedback, consolidation) |
memory_deleted |
Memory deleted (expired, negative feedback threshold) |
feedback_recorded |
Feedback saved |
Push event format:
{
"event": "memory_created",
"data": {
"memory_id": "abc123",
"content": "...",
"memory_type": "fact",
"created_at": "2026-03-06T01:30:00Z"
}
}
Per-Tenant Isolation¶
The WebSocket event bus is isolated per tenant. Clients only receive push events for their own tenant's memories. Tenant context is derived from the JWT token when auth is enabled.
Python Example¶
import asyncio
import websockets
import json
async def main():
async with websockets.connect("ws://localhost:8765/ws") as ws:
# Store a memory
await ws.send(json.dumps({
"command": "remember",
"payload": {"content": "Test memory", "priority": 5}
}))
response = await ws.recv()
print(json.loads(response))
asyncio.run(main())