DCP vs. CloudEvents
CloudEvents (a CNCF Graduated project) standardizes the envelope around any event: required attributes id, source, specversion, type, plus optional metadata, with no restriction on what the data field contains. DCP standardizes the coordination vocabulary that can fill that data field — they are stackable layers, not competing specs.
Why this comparison exists
Section titled “Why this comparison exists”DCP is sometimes described as “the CloudEvents of coordination events,” and that phrase invites a natural but wrong question: does DCP replace CloudEvents? It doesn’t. CloudEvents was never in the business of defining what an event means — its spec is explicit that it “does not place any restriction on the type of” the data field. DCP was never in the business of defining how an event is labeled, routed, or bound to a transport protocol. Read together, the two specs describe adjacent problems: one wraps, one fills.
Comparison
Section titled “Comparison”| DCP | CloudEvents | |
|---|---|---|
| Layer | Coordination-event vocabulary (what’s inside the payload) | Event envelope / metadata format (what wraps any payload) |
| What it standardizes | 8 closed entity types (Project, Task, Dependency, ArchitectureImpact, Decision, ReviewRequest, Finding, Milestone), an open verb vocabulary, and delta/refs semantics | Required context attributes (id, source, specversion, type) and optional ones (datacontenttype, dataschema, subject, time) |
| Payload / data model | A DcpMessage envelope carrying exactly one Event, with entity_type, verb, entity_id, and at least one of entity/delta/refs | A data field of unspecified, application-defined shape — CloudEvents’ spec explicitly leaves this open |
| Domain | One domain: software-project coordination between agents and humans | Any domain — order events, IoT telemetry, webhook payloads, Kubernetes changes, or a DCP message |
| Cross-field semantic rule | message_type MUST equal <entity_type>.<verb>; on conflict the body wins and the message is malformed (a rule plain JSON Schema cannot express) | No equivalent cross-field rule; type is a free-form reverse-DNS-style string chosen by the producer |
| Governance / status | Apache-2.0 code and schemas, CC-BY-4.0 docs; governed by the founding maintainers | CNCF Graduated (highest CNCF maturity tier), reached that status 2024-01-25 |
| Relationship | Can ride as CloudEvents data | Can carry a DCP message as its data — yes, this composes directly |
Can I use both together?
Section titled “Can I use both together?”Yes, and this is the intended pattern rather than an edge case. A DCP message is just JSON, and CloudEvents’ data field accepts any JSON. To carry a DCP event inside a CloudEvents envelope:
- Set the CloudEvents
typeattribute to the reverse-DNS formorg.devcopro.v1.<entity>.<verb>(for example,org.devcopro.v1.task.completed), derived from the event body. - Set
datacontenttypetoapplication/json, and pointdataschemaathttps://schemas.devcopro.org/v1/dcp-message.schema.jsonso a consumer knows how to parse and validatedatabefore it even looks inside. - Place the full
DcpMessage—dcp_version,message_id,message_type,issued_at,body, and anyextensions— unchanged inside the CloudEventsdatafield. - Let
idandsource(CloudEvents’ idempotency and origin attributes) do CloudEvents’ job, whilemessage_idandattributed_tocontinue to do DCP’s descriptive job. Neither field set replaces the other — and deliveries are deduped on (source,id), never onmessage_id.
These rules — including the occurred_at-only mapping for CE time and the broker-immutability requirement on data — are normative in the DCP-over-CloudEvents binding.
The result is one wire message with two layers of meaning: CloudEvents tells any generic event router how to label, dedupe, and route the envelope; DCP tells a coordination-aware consumer what actually happened to the project. A message queue, Kafka topic, or webhook receiver that only understands CloudEvents can still route the message correctly without ever parsing data — exactly the separation of concerns CloudEvents was designed to enable, and exactly why it needed a vocabulary like DCP to fill it for this domain. For the reasoning behind keeping DCP itself out of the transport-binding business, see why a coordination vocabulary is a distinct layer and DCP’s transport-neutral design. For the full envelope field list DCP puts inside that data slot, see the envelope reference; for how that envelope stays compatible across versions, see versioning and compatibility. For how DCP stacks against other adjacent specs, see the comparison hub.
By InterIP Networks · Last updated 2026-07-06.