Event Grid CloudEvents Schema
Azure Event Grid supports two event schema formats: the proprietary Event Grid Schema and the open-standard CloudEvents Schema. CloudEvents is a specification developed by the Cloud Native Computing Foundation (CNCF) to standardize how events are described across different cloud providers and platforms. Using CloudEvents makes your event-driven solutions portable and interoperable.
Why CloudEvents Exists
Different cloud providers invented their own event formats. An event from AWS looks different from an event from Azure, which looks different from an event from Google Cloud. Applications consuming events from multiple sources had to write separate parsing logic for each format.
BEFORE CloudEvents (Fragmented World):
Azure Event Grid event:
{ "id", "topic", "subject", "eventType", "eventTime", "data" }
AWS EventBridge event:
{ "id", "source", "detail-type", "time", "detail" }
Google Cloud Pub/Sub event:
{ "message": { "data", "attributes", "messageId", "publishTime" } }
→ Each platform has different field names
→ Consumers need different parsers for each source
AFTER CloudEvents (Unified World):
CloudEvents event (from ANY cloud):
{
"specversion": "1.0",
"id": "...",
"source": "...",
"type": "...",
"time": "...",
"data": { ... }
}
→ Same field names everywhere
→ One parser works for all sources
CloudEvents Schema Structure
CloudEvents defines a small set of required and optional attributes. Every compliant event carries these fields regardless of which cloud or platform produced it.
Required Attributes
| Attribute | Type | Description | Example |
|---|---|---|---|
| specversion | String | CloudEvents spec version | "1.0" |
| id | String | Unique identifier for this event | "abc123-def456" |
| source | URI | Who produced the event | "/subscriptions/.../storageAccounts/mystorage" |
| type | String | Type of event that occurred | "Microsoft.Storage.BlobCreated" |
Optional Attributes
| Attribute | Description | Example |
|---|---|---|
| time | When the event occurred (RFC 3339) | "2024-09-15T10:22:05Z" |
| datacontenttype | Content type of the data field | "application/json" |
| dataschema | URI pointing to the schema definition | "https://example.com/schemas/v1" |
| subject | Topic-relative path to the event subject | "/blobServices/default/containers/images/blobs/photo.jpg" |
CloudEvents vs Event Grid Schema Comparison
Same BlobCreated event in both formats:
Event Grid Schema:
{
"id": "b6d521d3",
"topic": "/subscriptions/abc/resourceGroups/myRG/.../mystorage",
"subject": "/blobServices/default/containers/images/blobs/photo.jpg",
"eventType": "Microsoft.Storage.BlobCreated",
"eventTime": "2024-09-15T10:22:05.000Z",
"data": {
"url": "https://mystorage.blob.core.windows.net/images/photo.jpg"
},
"dataVersion": "1.0"
}
CloudEvents Schema:
{
"specversion": "1.0",
"id": "b6d521d3",
"source": "/subscriptions/abc/resourceGroups/myRG/.../mystorage",
"type": "Microsoft.Storage.BlobCreated",
"time": "2024-09-15T10:22:05Z",
"subject": "/blobServices/default/containers/images/blobs/photo.jpg",
"datacontenttype": "application/json",
"data": {
"url": "https://mystorage.blob.core.windows.net/images/photo.jpg"
}
}
Key differences: CloudEvents uses source instead of topic, type instead of eventType, and time instead of eventTime. CloudEvents adds specversion and datacontenttype.
Choosing CloudEvents in Event Grid
You select the schema format when creating a custom topic or event subscription.
Create a Custom Topic with CloudEvents Schema
az eventgrid topic create \ --resource-group myResourceGroup \ --name myCustomTopic \ --location eastus \ --input-schema cloudeventschemav1_0
Create a System Topic Subscription with CloudEvents Schema
az eventgrid event-subscription create \ --name mySubscription \ --source-resource-id <storage-account-resource-id> \ --endpoint <webhook-url> \ --event-delivery-schema cloudeventschemav1_0
Note: System Topics from Azure services (like Blob Storage) always produce events in Event Grid Schema format internally. When you select CloudEvents for a subscription, Event Grid converts the events before delivery.
Publishing CloudEvents to a Custom Topic
HTTP Request Format
POST https://myTopic.eastus-1.eventgrid.azure.net/api/events
Content-Type: application/cloudevents+json; charset=utf-8
aeg-sas-key: <key>
{
"specversion": "1.0",
"type": "com.myapp.order.placed",
"source": "/myapp/orders",
"id": "order-001-2024",
"time": "2024-09-15T10:30:00Z",
"subject": "/orders/premium/001",
"datacontenttype": "application/json",
"data": {
"orderId": "ORD-001",
"customerId": "CUST-456",
"amount": 199.99
}
}
For CloudEvents, the Content-Type header is application/cloudevents+json instead of application/json. For a batch of events, use application/cloudevents-batch+json.
CloudEvents HTTP Binding
CloudEvents defines how event attributes map to HTTP headers and body in two content modes.
Binary Content Mode
Event attributes go in HTTP headers. The event body contains only the data payload.
POST /events HTTP/1.1
ce-specversion: 1.0
ce-type: com.myapp.order.placed
ce-source: /myapp/orders
ce-id: order-001
ce-time: 2024-09-15T10:30:00Z
Content-Type: application/json
{
"orderId": "ORD-001",
"amount": 199.99
}
Structured Content Mode
All event data including attributes goes in the body as a single JSON object. This is the mode Azure Event Grid uses.
POST /events HTTP/1.1
Content-Type: application/cloudevents+json
{
"specversion": "1.0",
"type": "com.myapp.order.placed",
"source": "/myapp/orders",
"id": "order-001",
"data": { "orderId": "ORD-001", "amount": 199.99 }
}
CloudEvents SDK Usage
The CloudEvents community provides official SDKs for C#, Java, Python, Go, and JavaScript.
C# with CloudEvents SDK
// Create a CloudEvent
var cloudEvent = new CloudEvent(
source: new Uri("/myapp/orders"),
type: "com.myapp.order.placed",
jsonSerializableData: new { orderId = "ORD-001", amount = 199.99 })
{
Id = Guid.NewGuid().ToString(),
Time = DateTimeOffset.UtcNow,
Subject = "/orders/premium/001",
DataContentType = "application/json"
};
// Serialize to JSON for sending
string json = JsonSerializer.Serialize(cloudEvent);
Consuming CloudEvents in an Azure Function
[FunctionName("ProcessCloudEvent")]
public static void Run(
[EventGridTrigger] CloudEvent cloudEvent,
ILogger log)
{
log.LogInformation("CloudEvent type: {type}", cloudEvent.Type);
log.LogInformation("CloudEvent source: {source}", cloudEvent.Source);
// Deserialize data payload
var orderData = cloudEvent.Data?.ToObjectFromJson<OrderData>();
log.LogInformation("Order ID: {id}", orderData?.OrderId);
}
The Azure Functions runtime accepts CloudEvent as the trigger type directly. No manual parsing is needed.
When to Use CloudEvents vs Event Grid Schema
| Scenario | Recommended Schema |
|---|---|
| All consumers are Azure services only | Event Grid Schema |
| Consumers include non-Azure systems | CloudEvents Schema |
| Events flow to multi-cloud environments | CloudEvents Schema |
| Open-source frameworks used (Knative, Dapr) | CloudEvents Schema |
| Existing Azure-only system, no migration planned | Event Grid Schema |
| New greenfield project | CloudEvents Schema (future-proof) |
Summary
CloudEvents is an open standard that defines a consistent event format across cloud providers. Azure Event Grid supports CloudEvents Schema 1.0 for custom topics and event subscriptions. CloudEvents uses familiar attribute names likesource, type, and time that work identically regardless of which platform produced the event. Choose CloudEvents for multi-cloud scenarios, open-source framework integrations, or new projects where portability matters. Use the CloudEvents SDK to produce and consume events with type-safe APIs rather than raw JSON parsing.