Separate event metadata from business data
Use the envelope for information that infrastructure can understand without interpreting business data. Event identity, source and type belong here. An invoice status, shipment quantity or account balance belongs in the payload. Avoid an envelope containing every possible business field; that design becomes another shared schema with difficult ownership.
CloudEvents defines required context attributes including specversion, id, source and type. It also defines optional attributes such as subject, time and datacontenttype. Adopting a standard vocabulary helps explain a contract, but does not by itself establish a transport, delivery guarantee or authorization model.
Define identity and time precisely
CloudEvents identifies an event using the combination of source and id. Preserve that pair when the same event is delivered again. If a transformation creates a genuinely new event, give it a new identity and retain an explicit causal reference where the architecture requires one.
CloudEvents time is intended to describe when the event occurred. If occurrence time cannot be determined, producers may use another time, but all producers for the same source must use the same method. Document that convention and store consumer receipt time separately for operational measurements. Neither a timestamp nor an identifier establishes a universal order across distributed producers. Clock accuracy and ordering are separate concerns.
- Occurrence time
- 10:00:00 UTC
- Consumer receipt time
- 10:00:03 UTC
15 January 2026. The consumer records receipt separately from the envelope's time.
Unknown occurrence time
time is optional. When occurrence time is unknown, a producer may use another timestamp. Producers for the same source must use and document a consistent method so consumers can interpret it.
An invoice approval event
The subject identifies the invoice; the type identifies its approval. The sequence belongs to the business stream and is meaningful only if its producer documents the allocation rule. Consumers should not infer a database transaction boundary from this field.
Validate the envelope and payload separately at ingress. Report malformed envelopes without logging unrestricted payloads. Quarantine unknown event types when automatic processing would be unsafe, while retaining enough metadata for the owner to diagnose a contract mismatch.
{
"specversion": "1.0",
"id": "evt_2048",
"source": "https://example.com/erp",
"type": "com.example.invoice.approved",
"subject": "invoices/inv_1042",
"time": "2026-01-15T10:00:00Z",
"datacontenttype": "application/json",
"data": {
"invoiceId": "inv_1042",
"status": "approved",
"sequence": 42
}
}Evolve the payload deliberately
The CloudEvents specversion describes the envelope specification, not the version of a business payload. Maintain a separate payload evolution policy. Explain which fields may be absent, whether unknown fields are tolerated and how consumers discover a breaking change.
A renamed status or a changed unit can be breaking even when the JSON shape still validates. Include semantic examples alongside structural schemas. Keep representative older messages in contract tests so new consumers prove they can handle the event history they may receive during recovery.
Carry only necessary context
Tenant references, correlation identifiers and policy classifications can support processing, but each needs a defined meaning and owner. An asserted tenant value is input to authorization checks, not evidence of authorization. Verify the sender and its permitted scope before using that value to select data.
Do not put credentials or unnecessary personal information in envelope attributes. Envelopes often appear in operational tools and logs. Review their visibility independently from payload storage, and ensure that error messages expose useful identifiers without leaking sensitive business content.