EVT-2Recommended
Wrap every event in one envelope
Give every event the same outer fields, whatever its type. Use the CloudEvents attributes id, source, type and specversion, plus time and dataschema.
How to do it
When each team invents its own wrapper, every consumer needs code per sender to find the ID and the type. CloudEvents 1.0 names four required attributes and binds them to HTTP, Kafka, AMQP and other transports. The pair of source and id is unique per event, so consumers use it to drop duplicates as Process each message once says. Put the business payload in data, and point dataschema at its versioned schema. Add a trace ID, so a message can be followed across services as Trace requests across services describes.
Examples
JSON example
{
"specversion": "1.0",
"id": "evt_7Hq2",
"source": "https://shop.example.com/orders",
"type": "com.example.shop.order.shipped.v2",
"time": "2026-10-27T09:14:03Z",
"dataschema": "https://shop.example.com/schemas/order-shipped/2.json",
"datacontenttype": "application/json",
"data": { "orderId": "ord_8f2k", "carrier": "postnord" }
}
Python example
import uuid
from datetime import datetime, timezone
def envelope(event_type: str, data: dict, schema_url: str) -> dict:
return {
"specversion": "1.0",
"id": str(uuid.uuid4()),
"source": "https://shop.example.com/orders",
"type": event_type,
"time": datetime.now(timezone.utc).isoformat(),
"dataschema": schema_url,
"datacontenttype": "application/json",
"data": data,
}
JavaScript example
import { randomUUID } from 'node:crypto';
export const envelope = (type, data, schemaUrl) => ({
specversion: '1.0',
id: randomUUID(),
source: 'https://shop.example.com/orders',
type,
time: new Date().toISOString(),
dataschema: schemaUrl,
datacontenttype: 'application/json',
data,
});
How to check
A contract test reads one message of each type from the test broker. Each has id, source, type, specversion and time, and no two messages share the same source and id.
Sources
Related rules
- EVT-11 Process each message once in Integration and events
- OPS-15 Trace requests across services in Operations and observability
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/events/contracts-and-schemas/event-envelope">Agent Wranglers integration and events playbook</a>. In code you write, add a comment next to it with the same link.