Acumatica · Cloudevents

CloudEvents Spec — A Field Guide

CloudEvents Spec — A Field Guide is the work that makes the systems talk. The API is the contract between the producer and the consumer; the contract is what determines whether.

John Kihiu12 min read

CloudEvents is a CNCF specification for describing event data in a common, vendor-neutral format. It doesn't define a transport or a broker — it defines the envelope: a small, consistent set of metadata attributes that let any producer, consumer, or piece of routing infrastructure agree on what an event is, regardless of whether it travels over Kafka, HTTP, MQTT, or AWS EventBridge.

The problem it actually solves

Before CloudEvents, every event-driven system invented its own envelope: some field called type, some called eventType, some called event_name; some with a timestamp, some without; ID generation left entirely to the producer. That's fine within a single team's system, but it becomes a real cost the moment you need to route events between systems, build generic tooling (a dead-letter viewer, a replay tool, a schema registry) that works across event sources, or integrate a SaaS webhook provider with your internal event bus. CloudEvents standardizes the metadata layer so that tooling can be built once and reused everywhere, while leaving the actual payload (the `data` field) completely open to whatever schema the domain needs.

The required and optional attributes

The spec (currently at 1.0, maintained by the CNCF) defines four required attributes: id (unique per source), source (a URI identifying the event's origin, e.g. /orders/service), specversion (the CloudEvents spec version, currently 1.0), and type (a reverse-DNS-style string like com.example.order.created). Optional attributes cover the common needs: time (RFC 3339 timestamp), datacontenttype (the MIME type of the payload, typically application/json), dataschema (a URI pointing at the payload's schema), and subject for further scoping within the source.

JSON · STRUCTURED-MODE CLOUDEVENT
{
  "specversion": "1.0",
  "type": "com.example.order.created",
  "source": "/orders/checkout-service",
  "id": "6c1f7e2a-3b4d-4e5f-9a1b-2c3d4e5f6a7b",
  "time": "2026-07-22T14:32:00Z",
  "datacontenttype": "application/json",
  "subject": "order/98213",
  "data": {
    "orderId": "98213",
    "total": 129.99,
    "currency": "USD"
  }
}

Binary mode vs. structured mode

Over HTTP, CloudEvents defines two encodings. Structured mode puts the entire envelope — attributes and data — into the HTTP body as a single JSON document, as shown above. Binary mode puts the CloudEvents attributes into HTTP headers (prefixed ce-, e.g. ce-type, ce-source, ce-id) and leaves the HTTP body as the raw payload with its native content type. Binary mode is generally preferred for HTTP webhook-style delivery because it lets intermediaries route on the headers without parsing the body; structured mode is more common over message brokers like Kafka where the whole message is opaque to the transport anyway.

CloudEvents describes the envelope, not the guarantee

The spec says nothing about delivery guarantees, ordering, or retries — those are properties of whatever transport carries the event (Kafka, SQS, EventBridge, a webhook). Two systems using CloudEvents can still have completely different reliability characteristics; standardizing the envelope doesn't standardize the delivery semantics underneath it.

Where it shows up in practice

Knative Eventing uses CloudEvents as its native format for all event routing. AWS EventBridge, Azure Event Grid, and Google Cloud's Eventarc all support emitting or accepting CloudEvents-formatted events, which is what makes it realistic to route a webhook from a third-party SaaS product through a CloudEvents-aware bus without writing a custom adapter for every source. The `sdk-*` repositories under the `cloudevents` GitHub org provide SDKs for Go, Java, JavaScript, Python, and others, handling the encoding/decoding so most teams never hand-construct the envelope themselves.

Adopt it at the edges first

You don't need to rewrite an internal event bus to use CloudEvents everywhere. The highest-value adoption point is usually at system boundaries — incoming webhooks, outbound integrations, or wherever events cross a team or company boundary — where the standardization actually saves someone from writing a bespoke parser.

Is it worth adopting for an internal-only system?

For a single team's internal event bus with no external consumers, CloudEvents adds a layer of standardization that may not pay for itself — a simpler home-grown envelope works fine as long as it's actually consistent. The spec earns its keep once there's more than one producer or consumer team, once tooling needs to be generic across event types, or once events need to cross into a platform (Knative, EventBridge, Event Grid) that already expects the format.

CloudEvents is a small, deliberately narrow spec — it standardizes the envelope so tooling and cross-system routing don't require a custom adapter for every event source, and it leaves the payload schema, delivery guarantees, and transport entirely up to you.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.