Every cloud vendor invented its own event envelope — until this
Publish an event on AWS EventBridge, Azure Event Grid, and Google Cloud Pub/Sub, and each one wraps your payload in a *different* JSON envelope with different field names for the same concepts: what happened, when, and who sent it. CloudEvents is a CNCF specification that standardizes that envelope, so event producers, routers, and consumers can be written once instead of once per cloud vendor. AWS, Azure, Google Cloud, Knative, and most serverless/event-mesh tooling now support emitting or consuming it.
The envelope: five required fields
Every CloudEvent — regardless of producer — carries the same core JSON structure:
{
"specversion": "1.0",
"type": "com.example.order.created",
"source": "/orders/api",
"id": "b1a2c3d4-e5f6-7890-abcd-ef1234567890",
"time": "2026-07-06T09:15:00Z",
"datacontenttype": "application/json",
"data": {
"orderId": "ord_9182",
"total": 149.97,
"customerId": "cus_42"
}
}| Field | Required | Meaning |
|---|---|---|
specversion | Yes | Which CloudEvents spec version this follows (currently 1.0) |
type | Yes | Reverse-DNS-style event name — what happened |
source | Yes | URI identifying the system or service that produced it |
id | Yes | Unique event identifier — the basis for deduplication |
time | No (but nearly always present) | ISO 8601 timestamp of when the event occurred |
datacontenttype | No | MIME type of data — usually application/json |
data | No | The actual event payload — your domain-specific JSON |
Everything above data is metadata *about* the event; data is the only part that's genuinely yours to define.
Two encodings: structured vs binary
CloudEvents can travel over HTTP in two modes. Structured mode puts the entire envelope — metadata and data — as the JSON HTTP body, exactly like the example above, with Content-Type: application/cloudevents+json. Binary mode instead puts the payload directly as the HTTP body and moves every metadata field into an HTTP header prefixed ce-:
POST /events HTTP/1.1
Content-Type: application/json
ce-specversion: 1.0
ce-type: com.example.order.created
ce-source: /orders/api
ce-id: b1a2c3d4-e5f6-7890-abcd-ef1234567890
ce-time: 2026-07-06T09:15:00Z
{ "orderId": "ord_9182", "total": 149.97, "customerId": "cus_42" }Binary mode is common with Kafka and message brokers where headers already exist as a first-class concept; structured mode is simpler when you're just POSTing JSON over HTTP.
Why the type field matters so much
type is meant to be a stable, versioned identifier consumers can route and filter on without inspecting data at all — the reverse-DNS style (com.example.order.created) exists specifically to avoid collisions across teams and vendors publishing to the same event bus. A well-designed type taxonomy is what makes an event mesh queryable and filterable at scale:
com.example.order.created
com.example.order.shipped
com.example.order.cancelled
com.example.payment.captured
com.example.payment.refundedEmitting CloudEvents from Node.js
// npm install cloudevents
import { CloudEvent, HTTP } from "cloudevents";
const event = new CloudEvent({
type: "com.example.order.created",
source: "/orders/api",
data: { orderId: "ord_9182", total: 149.97 },
});
const message = HTTP.binary(event); // { headers, body } ready to POSTWhere you'll actually meet CloudEvents
- Knative Eventing (Kubernetes) uses CloudEvents as its native event format between brokers and triggers.
- AWS EventBridge, Azure Event Grid, Google Eventarc all support emitting or receiving CloudEvents-formatted payloads alongside their native formats.
- Serverless functions (especially multi-cloud or portable ones) use it so the same function code can react to an event regardless of which cloud triggered it.
- Webhooks — some platforms now offer a CloudEvents-formatted webhook payload as an alternative to a bespoke format, specifically so consumers can reuse existing CloudEvents tooling.
CloudEvents vs a hand-rolled webhook envelope
If you've read a guide on designing webhook JSON payloads, you've already seen most of these ideas — a unique id, a type, a data object. CloudEvents' value is standardizing the *field names* so tooling (routers, schema registries, SDKs) can be generic instead of per-vendor. If you're building an internal event bus with only your own consumers, a custom envelope works fine; CloudEvents pays off once other teams, vendors, or cloud services need to interoperate with your events.