Skip to main content
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:
POST /v1/users/ws-ticket
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
}
FieldTypeDescription
collectionsstring[]Collection UUIDs to receive. An empty list means every collection readable by the ticket holder.
event_typesstring[]Event type filter. An empty list receives every event type.
last_ack_seqintegerOptional 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:
TypePayload
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.