MemMesh — persistent, self-improving memory for AI agents. Get started →
API ReferenceEvents & Alerts

Events & Alerts API

MemMesh is proactive as well as reactive: the engine appends events to a durable log, and alert rules react to matching events synchronously.

Emit an event

POST /api/v1/projects/{projectId}/lattice/events/emit

Append an event to the log. The alert evaluator runs synchronously inside this call, so “event emitted” implies “rules matched and dispatched”. Emission is idempotent — re-emitting the same (projectId, dedupeKey) silently drops.

{
  "eventType": "prediction.imminent",
  "subject": { "kind": "customer", "externalId": "acct-42" },
  "severity": "warn",
  "payloadJson": "{\"expectedAt\":\"2026-07-18T15:00:00Z\"}",
  "sourcePatternId": "mem_…"
}

severity is info | warn | critical (defaults to info). The response reports whether the event was inserted and how many alert rules dispatched:

{ "emitted": true, "event": { "id": "evt_…", "eventType": "prediction.imminent", "severity": "warn", "occurredAt": "…" }, "alertDispatches": 1 }

Predictions can emit events for you: call POST /lattice/predict with emitEvents: true to fire a prediction.imminent event for each prediction due within imminentWithinHours. See Predictions.

Poll events

GET /api/v1/projects/{projectId}/memory-events?since=…&limit=…&eventTypes=…

Walk the log. Pass the last returned event’s occurredAt back as since to page forward; eventTypes is a comma-separated filter.

[
  {
    "id": "evt_…",
    "eventType": "prediction.imminent",
    "subject": { "kind": "customer", "externalId": "acct-42" },
    "severity": "warn",
    "payload": { "expectedAt": "2026-07-18T15:00:00Z" },
    "sourceMemoryIds": [],
    "sourcePatternId": "mem_…",
    "emittedByPack": null,
    "occurredAt": "2026-07-13T00:00:00Z"
  }
]

Alert rules

CRUD under /api/v1/projects/{projectId}/memory-alerts.

MethodPathPurpose
GET/memory-alertsList rules.
GET/memory-alerts/:alertIdFetch one rule.
POST/memory-alertsCreate a rule.
PATCH/memory-alerts/:alertIdPatch any subset of fields.
DELETE/memory-alerts/:alertIdDelete a rule + its fire history.
GET/memory-alerts/:alertId/firesList recent fires (last 100).

A rule has four JSON parts:

{
  "name": "Imminent churn → Slack",
  "enabled": true,
  "trigger": { "kind": "engine-event", "eventTypes": ["prediction.imminent"] },
  "filter": { "subjectKind": "customer" },
  "notify": [ { "kind": "webhook", "url": "https://hooks…" } ],
  "throttle": { "cooldownMinutes": 60, "dedupOn": "subject+rule" }
}
  • trigger.kindengine-event | segment-change | pattern-emerged.
  • filter — narrow by subjectKind, id pattern, categories, or a metadata match.
  • notify — an array of channels; a channel can also writeAs a memory back into a scope.
  • throttlemaxPerHour, cooldownMinutes, and dedupOn (subject | subject+rule | rule).

The number of active rules counts against the active-triggers entitlement. A GET …/fires row carries the dedupeKey and parsed deliveryResults per channel.