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

AttributeTypeDescriptionExample
specversionStringCloudEvents spec version"1.0"
idStringUnique identifier for this event"abc123-def456"
sourceURIWho produced the event"/subscriptions/.../storageAccounts/mystorage"
typeStringType of event that occurred"Microsoft.Storage.BlobCreated"

Optional Attributes

AttributeDescriptionExample
timeWhen the event occurred (RFC 3339)"2024-09-15T10:22:05Z"
datacontenttypeContent type of the data field"application/json"
dataschemaURI pointing to the schema definition"https://example.com/schemas/v1"
subjectTopic-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

ScenarioRecommended Schema
All consumers are Azure services onlyEvent Grid Schema
Consumers include non-Azure systemsCloudEvents Schema
Events flow to multi-cloud environmentsCloudEvents Schema
Open-source frameworks used (Knative, Dapr)CloudEvents Schema
Existing Azure-only system, no migration plannedEvent Grid Schema
New greenfield projectCloudEvents 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 like source, 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.