Event Grid
Compatible with the azure-messaging-eventgrid publisher SDK, the
azure-resourcemanager-eventgrid / ARM management plane, and any HTTP client. Event Grid is the
Azure counterpart of an event router (publish/subscribe with webhook fan-out) — a Custom Topic
receives events and pushes them to subscriber webhook endpoints.
HTTP-only — no Docker. Topics, subscriptions, publishing, and delivery are all in-process. There is no sidecar.
Features
- Custom Topics — CreateOrUpdate, Get, Delete, List (by resource group and by subscription),
with
properties.endpointandinputSchema(EventGridSchemadefault, orCloudEventSchemaV1_0) - Access keys —
listKeysreturns{key1, key2};regenerateKeyrotates one of them - Event subscriptions — classic scoped
eventSubscriptionswith a WebHook destination,filter(subjectBeginsWith,subjectEndsWith,includedEventTypes,isSubjectCaseSensitive), andretryPolicy - Publish —
POST /api/eventsaccepts a JSON array of events in the Event Grid or CloudEvents 1.0 schema - Delivery — events are fanned out asynchronously to matching subscribers, retried per the
subscription's
retryPolicywith exponential backoff - Validation handshake — creating a webhook subscription triggers a
Microsoft.EventGrid.SubscriptionValidationEvent(or, for CloudEvents, theOPTIONSabuse-protection probe)
Endpoints
Management operations use ARM paths; publishing uses the topic's data-plane endpoint.
PUT /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.EventGrid/topics/{name}
GET /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.EventGrid/topics/{name}
DELETE /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.EventGrid/topics/{name}
POST .../topics/{name}/listKeys
POST .../topics/{name}/regenerateKey # body: {"keyName":"key1"|"key2"}
GET /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.EventGrid/topics
GET /subscriptions/{sub}/providers/Microsoft.EventGrid/topics
PUT {topicId}/providers/Microsoft.EventGrid/eventSubscriptions/{name}
GET {topicId}/providers/Microsoft.EventGrid/eventSubscriptions/{name}
DELETE {topicId}/providers/Microsoft.EventGrid/eventSubscriptions/{name}
GET {topicId}/providers/Microsoft.EventGrid/eventSubscriptions
POST /{name}-eventgrid/api/events # data-plane publish (topic endpoint)
Quickstart
1 — Create a topic
curl -s -X PUT \
"http://localhost:4577/subscriptions/my-sub/resourceGroups/my-rg/providers/Microsoft.EventGrid/topics/my-topic?api-version=2025-02-15" \
-H "Content-Type: application/json" \
-d '{"location":"eastus","properties":{"inputSchema":"EventGridSchema"}}'
The response carries the data-plane endpoint:
{
"name": "my-topic",
"type": "Microsoft.EventGrid/topics",
"properties": {
"provisioningState": "Succeeded",
"endpoint": "http://localhost:4577/my-topic-eventgrid/api/events",
"inputSchema": "EventGridSchema"
}
}
Fetch the keys with POST .../topics/my-topic/listKeys → {"key1":"…","key2":"…"}.
2 — Subscribe a webhook
curl -s -X PUT \
"http://localhost:4577/subscriptions/my-sub/resourceGroups/my-rg/providers/Microsoft.EventGrid/topics/my-topic/providers/Microsoft.EventGrid/eventSubscriptions/my-sub-1?api-version=2025-02-15" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"destination": {"endpointType": "WebHook", "properties": {"endpointUrl": "https://my-app.example/hook"}},
"filter": {"subjectBeginsWith": "/orders"}
}
}'
The emulator immediately runs the validation handshake against the webhook (a
SubscriptionValidationEvent; the subscriber must echo {"validationResponse": "<code>"}).
3 — Publish events
from azure.core.credentials import AzureKeyCredential
from azure.eventgrid import EventGridPublisherClient, EventGridEvent
client = EventGridPublisherClient(
"http://localhost:4577/my-topic-eventgrid/api/events", AzureKeyCredential("<key1>"))
client.send([EventGridEvent(
subject="/orders/123", event_type="Order.Created",
data={"orderId": 123}, data_version="1.0")])
Events whose subject matches the subscription filter are POSTed (as a JSON array) to the webhook,
with topic set to the topic's full resource id and an aeg-event-type: Notification header.
Configuration
floci-az:
services:
event-grid:
enabled: true
default-region: eastus # region label baked into the topic endpoint host text
max-delivery-attempts: 30 # default when a subscription omits its own retryPolicy
| Env var | Default | Description |
|---|---|---|
FLOCI_AZ_SERVICES_EVENT_GRID_ENABLED |
true |
Enable/disable the service |
FLOCI_AZ_SERVICES_EVENT_GRID_DEFAULT_REGION |
eastus |
Region label for the topic endpoint |
FLOCI_AZ_SERVICES_EVENT_GRID_MAX_DELIVERY_ATTEMPTS |
30 |
Default delivery attempts |
Notes & limitations
- WebHook destinations only. Service Bus, Event Hub, Storage Queue, and Azure Function destinations, plus Domains, Partner/System Topics, and the Event Grid Namespace (MQTT/pull) surface are out of scope.
- Dead-lettering is best-effort. When delivery exhausts
retryPolicy.maxDeliveryAttempts, the event is logged and dropped; it is not written to adeadLetterDestinationblob container. - Auth is permissive. The
aeg-sas-keyheader is accepted but not validated against the topic keys (dev mode), matching the rest of the emulator. CustomEventSchemais accepted but treated as the Event Grid schema.- Advanced filters (
advancedFilters, array filtering) are accepted but not evaluated.