This page covers enterprise integration surfaces that are intentionally available to deployed clients but are not part of the generated public OpenAPI export yet.
The contracts below are stable for documented required fields during the v0.2 line. Nebula may add optional fields, event types, or workflow metadata without a breaking-version bump. Treat unknown fields and unknown event types as forward-compatible extensions.
Live memory events
Nebula exposes live memory events over:
GET /v1/ws/memory-events?ticket=<single-use-ticket>
This is a WebSocket upgrade endpoint. Connect with ws:// or wss://; a plain HTTP GET will not stream events.
Mint a ticket with:
The ticket is single-use and short-lived. The WebSocket endpoint is not shown in OpenAPI because FastAPI excludes WebSocket routes from the HTTP schema.
Client frames
Subscribe after the socket opens:
{
"action": "subscribe",
"collections": ["COLLECTION_UUID"],
"event_types": ["ingestion_progress", "memory_unconfident"],
"last_ack_seq": 123
}
| Field | Type | Description |
|---|
collections | string[] | Collection UUIDs to receive. An empty list means every collection readable by the ticket holder. |
event_types | string[] | Event type filter. An empty list receives every event type. |
last_ack_seq | integer | Optional replay cursor from the last processed event. |
Ack processed events:
{ "action": "ack", "seq": 124 }
Send a heartbeat when the client wants an application-level keepalive:
{ "action": "heartbeat" }
Unsubscribe without closing the socket:
{ "action": "unsubscribe" }
Server frames
Successful subscribe:
{
"action": "subscribed",
"collections": ["COLLECTION_UUID"],
"event_types": ["ingestion_progress"]
}
Event frame:
{
"action": "event",
"seq": 124,
"event_id": "EVENT_UUID",
"type": "ingestion_progress",
"collection_id": "COLLECTION_UUID",
"payload": {},
"ts": "2026-05-27T18:30:00Z"
}
Error frames use action: "error" or action: "subscribe_error" with a reason string. Heartbeats receive:
{ "action": "heartbeat_ack" }
Event types
Current published event types:
| Type | Payload |
|---|
ingestion_progress | { "engram_id": string, "stage": string, "user_stage": "reading" | "structuring" | "indexing" | "complete" | "failed", "current": integer, "total": integer, "message": string | null } |
memory_unconfident | { "query": string, "reason": "no_results" | "low_activation" | "low_fact_confidence", "entity_count": integer, "fact_count": integer, "episode_count": integer, "source_count": integer, "avg_activation": number, "max_activation": number, "avg_fact_confidence": number } |
A machine-readable schema is available at /enterprise/memory-events.schema.json in the docs bundle.
Delivery semantics
The Postgres backend appends events to public.memory_events, emits LISTEN/NOTIFY, and replays missed events from the durable event log using last_ack_seq. Delivery is at least once within the retention window. Clients should ack after processing and deduplicate by seq on the WebSocket stream.
Memory events are no longer published through the legacy SQS/API Gateway WebSocket path. Postgres is the single event backend for enterprise deployments.
Event injection
There is no public endpoint for posting arbitrary memory events into Nebula. Smoke tests should use synthetic JSONL fixtures or trigger normal memory ingestion and subscribe to ingestion_progress.
Nebula has an environment-gated test-seed router for internal connector E2E tests. It is not a production ingestion or replay API.