An event contract must identify the event, describe its meaning, carry a compatible payload, and show where applications send or receive it. CloudEvents and AsyncAPI help with different parts of that contract. Neither specification creates broker durability, consumer idempotency, or exactly-once external effects.
Quick answer
Use CloudEvents to standardize event-envelope attributes such as identity, source, type, subject, time, and data content. Use an AsyncAPI document to describe applications, channels, messages, and send or receive operations. Keep payload evolution, authorization, delivery, retention, and replay rules explicit alongside those machine-readable definitions.
Prerequisites
Read Event-Driven Architecture Decisions and JSON Schema vs OpenAPI Schema. This lesson assumes you can separate a message envelope from the business data inside it.
Envelope and payload are different contracts
The envelope answers routing and interpretation questions: which event is this, who produced it, what kind is it, and which resource does it concern? The payload carries domain data such as an order ID, version, currency, and amount. Reusing the same field name for both levels creates ambiguity during transformation and replay.
A compact event might look like this:
{
"specversion": "1.0",
"id": "evt_01J...",
"source": "/services/orders",
"type": "com.example.order.accepted.v1",
"subject": "orders/ord_123",
"time": "2026-08-18T14:30:00Z",
"datacontenttype": "application/json",
"data": {
"orderId": "ord_123",
"orderVersion": 4,
"total": { "currency": "USD", "minorUnits": 2599 }
}
}
The stable id supports deduplication evidence. It should represent one logical event across retries, not a new value on every publication attempt. time records a producer observation; it is not a trustworthy global order across machines.
CloudEvents scope
CloudEvents defines common event attributes and protocol bindings. A Kafka binding explains how attributes may map to records. It does not decide the application’s partition key, ACL, retention, schema compatibility, or side-effect transaction. Those remain architecture and operations decisions.
Choose event types that reflect durable business meaning. A version suffix can make incompatible semantic change visible, but versioning every harmless additive field creates unnecessary fragmentation. Document what consumers may ignore and what producers promise to retain.
AsyncAPI scope
An AsyncAPI document describes a message-driven application. Channels identify addressable destinations, messages describe content, and operations state whether an application sends or receives on a channel. Protocol bindings add Kafka-specific or other transport-specific information without turning the entire contract into a broker configuration dump.
asyncapi: 3.1.0
info:
title: Order Events
version: 1.0.0
channels:
orderEvents:
address: order-events
messages:
orderAccepted:
$ref: '#/components/messages/OrderAccepted'
operations:
publishOrderAccepted:
action: send
channel:
$ref: '#/channels/orderEvents'
The document is useful for review, documentation, validation, and code-generation workflows. Generated code does not replace business authorization, idempotency, or compatibility tests.
Failure scenario
A producer changes total from integer cents to a decimal string without changing the schema contract. One consumer rejects the record and another silently rounds it. The broker delivered the bytes successfully, but the event contract failed. Compatibility checks in CI and consumer-driven fixtures would have exposed the change before publication.
Security and privacy boundaries
Do not place secrets, access tokens, raw payment data, or unnecessary personal information in an event because retention and fan-out increase exposure. Document classification, encryption, access, deletion, and redaction rules. Correlation attributes should be useful but bounded; customer IDs and message IDs often belong in protected logs, while email addresses do not belong in metric labels.
Common mistakes
- Treating CloudEvents as a payload schema registry.
- Treating AsyncAPI as proof that the deployed broker matches the document.
- Generating a new event ID on retry and defeating consumer deduplication.
- Encoding transport-specific headers inside the business payload.
- Publishing sensitive snapshots to every consumer “for convenience.”
Production validation
Validate example events against the envelope and payload schemas. Run backward and forward compatibility fixtures for supported consumer versions. Compare deployed topics, ACLs, and application operations with the AsyncAPI document. Replay recorded non-sensitive fixtures through new consumers, verify unknown fields are handled as promised, and confirm rejected records enter a bounded operated path rather than an infinite retry loop.
Sources
- CloudEvents Specification, stable v1.0.2 materials, accessed 2026-08-18: https://github.com/cloudevents/spec.
- AsyncAPI documentation and specification resources, accessed 2026-08-18: https://www.asyncapi.com/docs.
- AsyncAPI document concepts, accessed 2026-08-18: https://www.asyncapi.com/docs/concepts/asyncapi-document.
Related reading
Continue with Event Schema Evolution and Compatibility and Transactional Outbox. The complete order appears in the Event-Driven Systems course and topic cluster; API contract parallels are covered in OpenAPI Explained.