Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kaireonai.com/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The KaireonAI Domain Event Stream publishes lightweight notifications whenever the platform records an interaction or makes a recommendation. Subscribers (analytics workers, ML feature pipelines, external sinks) can consume these events without polling the OLTP database. This stream is separate from the POST /api/v1/events ingestion endpoint, which accepts inbound customer behavior events.

Topics

TopicWhen firedCarries
interaction.recorded.v1Every successful insert into InteractionHistory (impressions, clicks, conversions, complaints, unsubscribes)tenantId, customerId, offerId, creativeId, channelId, interactionType, outcomeTypeKey, campaignId, recommendationId, timestamp
decision.made.v1Every successful POST /api/v1/recommend decisiontenantId, customerId, recommendationId, offersReturned, topOfferId, topPropensity, decisionFlowKey, timestamp

Event envelope

Every event is published as JSON with this shape:
{
  "type": "interaction.recorded.v1",
  "timestamp": "2026-04-28T12:00:00.000Z",
  "payload": {
    "tenantId": "...",
    "customerId": "...",
    "offerId": "...",
    "creativeId": "...",
    "channelId": "...",
    "interactionType": "click",
    "outcomeTypeKey": "click",
    "campaignId": null,
    "recommendationId": "...",
    "timestamp": "2026-04-28T12:00:00.000Z"
  }
}

Choosing a backend

The publisher backend is selected via the EVENT_PUBLISHER environment variable. Pick the trade-off that fits your operational story — durability, cost, ops weight all vary.
EVENT_PUBLISHERBackendDurabilityWhen to use
redis (default)Redis pub/subNone — fire-and-forget; consumers must be onlineLocal dev with Upstash or docker compose up redis; playground; small self-hosted setups where the OLTP InteractionHistory is enough
kafka / redpandaKafka API (kafkajs)Replayable with consumer groups + offsetsLocal dev with docker compose --profile kafka up redpanda; self-hosted Kafka or Redpanda; Confluent Cloud; Aiven
msk / aws_mskAmazon MSK (IAM-auth Kafka)ReplayableAWS-native deployments using Managed Streaming for Apache Kafka
eventbridgeAWS EventBridgePay-per-event, durable, fan-out to many AWS targetsWhen downstream consumers are AWS Lambda / Step Functions / SQS
kinesisAWS Kinesis Data StreamsReplayable, 24-hr to 365-day retentionWhen downstream consumers want streaming-shard semantics
Switch backends without code changes — set EVENT_PUBLISHER and the per-backend env vars below. Topic names + event payloads stay identical, so subscribers don’t need to be rewritten.

Local dev with Redpanda (free Kafka API)

Redpanda is a Kafka-compatible broker that runs as a single binary, no Zookeeper, no JVM. It is included as an optional Docker Compose profile:
# Start the broker (~5 seconds)
docker compose --profile kafka up -d redpanda

# Point the platform at it
export EVENT_PUBLISHER=kafka
export KAFKA_BROKERS=localhost:19092   # host port (in-cluster clients use redpanda:9092)
npm run dev
For Redpanda Cloud Serverless (free tier survives indefinitely for low-traffic):
export EVENT_PUBLISHER=kafka
export KAFKA_BROKERS=your-cluster.redpanda.com:9092
export KAFKA_TLS_ENABLED=true
export KAFKA_SASL_MECHANISM=scram-sha-256
export KAFKA_SASL_USERNAME=<from-redpanda-cloud-console>
export KAFKA_SASL_PASSWORD=<from-redpanda-cloud-console>

Durability — what each backend gives you

  • redis: none. Consumers must be online when an event fires. If no subscriber is connected to a topic, the event is silently dropped.
  • kafka / redpanda / msk: events are persisted to the broker. Consumers can replay from any offset within the configured retention window (default Kafka retention is 7 days). Multiple consumer groups read independently.
  • eventbridge: durable per-event delivery to subscribed targets. No replay (use SQS DLQ for failures).
  • kinesis: durable shards with 24-hour to 365-day replay window.
In all backends, the publish call is fail-open: if the broker is unreachable or required env vars are missing, the platform logs a warning and continues. The OLTP source of truth remains InteractionHistory — query it directly if you need a replayable record older than your stream’s retention window.

Configuration reference

Common

Env varRequiredNotes
EVENT_PUBLISHERNoOne of redis (default) / kafka / redpanda / msk / aws_msk / eventbridge / kinesis

Redis backend (EVENT_PUBLISHER=redis)

Env varRequiredNotes
REDIS_URLWhen EVENT_PUBLISHER=redisIf unset on the redis backend, event stream is disabled; platform keeps functioning

Kafka / Redpanda backend (EVENT_PUBLISHER=kafka or redpanda)

Env varRequiredNotes
KAFKA_BROKERSYesComma-separated host:port list
KAFKA_CLIENT_IDNoDefaults to kaireon-platform
KAFKA_TLS_ENABLEDNotrue to enable TLS
KAFKA_SASL_MECHANISMNoplain, scram-sha-256, or scram-sha-512
KAFKA_SASL_USERNAME / KAFKA_SASL_PASSWORDWhen SASL enabledAuth credentials
KAFKA_CONSUMER_GROUP_IDNoDefaults to kaireon-consumers

MSK backend (EVENT_PUBLISHER=msk)

Env varRequiredNotes
MSK_BROKERSYesComma-separated bootstrap brokers
MSK_REGIONNoDefaults to us-east-1
MSK_AUTH_MODENoiam_role (default) or sasl_scram
MSK_ROLE_ARNWhen IAM modeIAM role for sigv4
MSK_SASL_USERNAME / MSK_SASL_PASSWORDWhen SASL mode
MSK_CONSUMER_GROUP_IDNo
MSK_TOPIC_PREFIXNoOptional prefix for all topics
(Equivalent env-var sets exist for eventbridge and kinesis — see platform/src/lib/infra/container.ts.)

Sample subscriber (ioredis)

import Redis from "ioredis";

const sub = new Redis(process.env.REDIS_URL!);

await sub.subscribe("interaction.recorded.v1");
await sub.subscribe("decision.made.v1");

sub.on("message", (channel, raw) => {
  const event = JSON.parse(raw);
  switch (channel) {
    case "interaction.recorded.v1":
      console.log("interaction:", event.payload);
      break;
    case "decision.made.v1":
      console.log("decision:", event.payload);
      break;
  }
});

Where it’s wired

Code pathSource file
Publisher singletonplatform/src/lib/events/interaction-events.ts
Redis backendplatform/src/lib/infra/redis-events.ts
InteractionStore.recordEventplatform/src/lib/infra/pg-interaction-store.ts
POST /api/v1/respondplatform/src/app/api/v1/respond/route.ts