DestinationsEvent envelope

Event envelope

Kafka and webhook destinations deliver a customer export body (specVersion 1.0) built by causet-realtime. That shape is stable for consumers. It is derived from the internal CommittedEventEnvelope on causet.committed-events.v1 (or a transitional PatchEvent conversion) — you do not receive the internal wire format on your topic/URL.

Dedupe on body field id (Kafka header causet-event-id, webhook header X-Causet-Event-Id). Delivery is at-least-once.


Export body (export_v1 / specVersion 1.0)

This is the default JSON value for Kafka records and the default webhook POST body (payloadFormat omitted or export_v1).

{
  "specVersion": "1.0",
  "id": "evt_1",
  "type": "jamlet.feed-item-published",
  "source": "causet://deployment/dep_1",
  "subject": "feed/feed_1",
  "time": "2026-07-30T15:35:12Z",
  "dataContentType": "application/json",
  "dataSchema": "causet://schemas/FeedItemPublished/1",
  "tenantId": "tenant_1",
  "projectId": "project_1",
  "environmentId": "main",
  "deploymentId": "dep_1",
  "streamId": "feed",
  "streamSequence": 42,
  "globalSequence": 99,
  "correlationId": "corr",
  "causationId": "cause",
  "data": { "title": "x" },
  "causet": {
    "destinationId": "dest_1",
    "subscriptionId": "sub_1",
    "deliveryId": "del_1",
    "replayId": null,
    "replay": false,
    "attempt": 1
  }
}
FieldTypeNotes
specVersionstringAlways "1.0" today
idstringStable Causet event id — dedupe key
typestringBusiness event type (subscription patterns match this)
sourcestringcauset://deployment/{deploymentId}, or causet://deployment/unknown
subjectstringTypically {streamId}/{entityId}
timestring (RFC3339)occurredAt, else committedAt, else send time (UTC)
dataContentTypestringAlways application/json
dataSchemastringcauset://schemas/{schema.name}/{schema.version}, or causet://schemas/{type}/1 if schema name empty
tenantIdstringPlatform / tenant
projectIdstringApplication
environmentIdstringFork (e.g. main) — omitted when empty
deploymentIdstringOmitted when empty
streamIdstringEntity stream
streamSequencenumberPer-stream sequence (maps from internal cursor)
globalSequencenumberOmitted when 0 / unavailable
correlationId / causationIdstringOmitted when empty
dataobjectEvent payload ({} if none)
causet.destinationIdstringDestination that delivered this record
causet.subscriptionIdstringMatching subscription
causet.deliveryIdstringThis delivery job id
causet.replayIdstring | nullSet on replay deliveries
causet.replaybooleantrue when replayId is non-empty
causet.attemptnumber1-based delivery attempt

There is no top-level eventType, payload, entityId, intentId, platformId, applicationId, or forkId in export_v1. Entity identity is in subject (and usually streamId). Tenancy uses tenantId / projectId / environmentId.


Kafka headers

Set on every Kafka destination record:

HeaderWhen
content-typealways → application/json
causet-spec-versionalways → 1.0
causet-event-idalways
causet-event-typealways
causet-delivery-idalways
causet-destination-idalways
causet-subscription-idalways
causet-replayalways → true / false
causet-global-sequencewhen globalSequence > 0
causet-stream-sequencewhen streamSequence > 0
causet-correlation-idwhen present
traceparentwhen a trace id is present (00-{traceId}-0000000000000000-01)

There are no causet-entity-id, causet-fork-id, or causet-intent-id headers on the Kafka export path.

Record key

Partition key strategy defaults to stream_id (fallback event_id). Other strategies: event_id, subject, correlation_id, constant. Ordering is only reliable for the same key within one partition — not a global total order.


Webhook headers

HeaderWhen
Content-Typealways → application/json
X-Causet-Event-Idalways
X-Causet-Event-Typealways
X-Causet-Delivery-Idalways
X-Causet-Destination-Idalways
X-Causet-Subscription-Idalways
X-Causet-Delivery-Attemptalways (attempt number)
X-Causet-Trace-Idwhen present
X-Causet-Signaturewhen HMAC signing is enabled
X-Verdant-Signaturesame value as X-Causet-Signature (compat)

Plus any static headers configured on the destination.


Webhook flat_v1 (optional)

If the webhook destination sets payloadFormat: flat_v1, the body is a flatter map (not export_v1):

FieldNotes
eventId / eventTypeSame ids as id / type above
platformId / applicationId / forkIdTenant aliases
streamId / entityId / intentIdStream coordinates
cursorStream sequence
timestampUnix millis
payloadEvent payload object
deliveryIdDelivery job id

Prefer export_v1 for new integrations so Kafka and webhooks share one schema.


Internal vs export (for operators)

LayerShapeAudience
Internal busCommittedEventEnvelope (eventId, eventType, payload, …)causet-realtime only
Customer exportexport_v1 above (id, type, data, causet, …)Your Kafka / webhook consumers