{
"id": "0b7c6a8e-3d1f-4c2a-9b55-1f2e8d7c4a10",
"type": "OrderPlaced",
"version": 2,
"occurredAt": "2026-03-14T10:22:05.120Z",
"source": "order-service",
"correlationId": "req-7f3a",
"causationId": "cmd-55e1",
"data": { "orderId": "o-1001", "total": 129.9 }
}
Every message should carry an id, a type and version, an event time, a source, and correlation and causation ids. Each one has a job:
- id: a unique id. Consumers use it to deduplicate redeliveries, so they don't process the same message twice.
- type and schema version: they let a consumer send the message to the right handler. They also tell it how to parse the message while several versions are live.
- occurredAt: when the event happened in the business sense. This is different from when it was published or consumed. It matters for ordering checks and for late data.
- source: the name of the service that produced the message. It helps with debugging and shows who owns the message.
- correlationId: one id shared by every message and log line from the same user request or workflow. It ties them together.
- causationId: the id of the message that directly caused this one. With it, you can rebuild the chain of messages.
Put this metadata in a consistent envelope (a standard wrapper around the payload) or in message headers. CloudEvents is a standard for exactly this envelope.
- A unique id lets consumers deduplicate messages.
- The type and version let consumers route and parse the message.
- The event time is kept separate from the processing time.
- The source shows who owns the message and helps debugging.
- Correlation and causation ids let you trace a request across messages.
Read more
- Event message (https://www.enterpriseintegrationpatterns.com/patterns/messaging/EventMessage.html)enterpriseintegrationpatterns.com
- Kafka events course (https://developer.confluent.io/courses/apache-kafka/events/)developer.confluent.io