Event schema governance

Define whether the event is a snapshot or a change

Build an event contract around one interpretation. A consumer needs to know whether it should replace a view, apply a transition or fetch more information.

In this article

Begin with the consumer's action

Consider a customer address change. A delivery service needs the address accepted for a particular shipment. A customer directory needs the latest contact address. Sending both services a vaguely named customer updated message invites each to make its own choice.

Write down the required action before choosing the payload. The shipment service may need an immutable delivery-address assignment. The directory may need a current-state projection. They can share source data without sharing an identical event contract.

Make the example unambiguous

An illustrative change event might identify the affected shipment, its new delivery address and the revision of that assignment. It should also explain what the revision orders. A sequence local to one shipment must not be treated as a global order across all shipments.

JSON example
{
  "eventId": "event-example-81",
  "eventType": "shipment.delivery-address-assigned",
  "contractVersion": 1,
  "shipmentId": "shipment-example-24",
  "assignmentRevision": 3,
  "addressId": "address-version-example-9"
}

This example references a versioned address. If the address service overwrites that record in place, the reference no longer provides a stable historical value. Either retain the addressed version or carry the necessary address fields under appropriate access controls.

Implement one interpretation at the boundary

Validate the incoming contract before converting it into the consumer's internal model. Keep that conversion in one place so older versions do not spread conditional logic throughout the application.

For a snapshot consumer, specify whether an older revision is ignored. For a change consumer, define what happens when an earlier event is missing. Do not apply a snapshot's replacement logic to a sequence of increments. Replacing a quantity with an increment can produce a plausible but incorrect result.

Save event processing identity with the local effect where the storage model permits. Duplicate delivery should not create another shipment assignment or repeat an external notification.

Prove the intended result

Use a short sequence with two changes, a duplicate and reversed arrival order. Record the expected local state after each message. Include a consumer restart between receipt and acknowledgement.

The test should explain the chosen semantics to a new maintainer. If the expected state is hard to write down, resolve the contract before adding more consumers. A precise example is cheaper to change now than several production interpretations later.

Primary sources

CloudEvents specification repository

References checked 11 September 2026.