9.2 Registering Service Endpoints: Webhooks, Azure Service Bus & Event Hub
Key Takeaways
- Webhooks post the execution context directly to an HTTP(S) endpoint you control, registered in the Plug-in Registration Tool with a name, endpoint URL, and one of three authentication types (HttpHeader, HttpQueryString, WebhookKey).
- WebhookKey authentication is the right choice for Azure Functions, since Functions expect their key under the query-string name 'code'.
- Azure Service Bus Queue delivers to a single consumer without requiring an always-on listener; Topic fans the same message out to multiple independently filtered subscriptions.
- One-way, Two-way, and REST are Service Bus contracts that require an actively listening consumer; Two-way and REST additionally let the listener return a value back to the calling plug-in.
- Azure Event Hub is built for high-volume, one-way telemetry and analytics ingestion rather than transactional request/reply integration, and only supports SAS authentication via a connection string.
Once you understand how Dataverse pushes event data out through IServiceEndpointNotificationService, the next decision is where that data should go. The Plug-in Registration Tool supports three destination families for a service endpoint — webhooks, Azure Service Bus, and Azure Event Hubs — and PL-400 expects you to recommend the right one for a given integration scenario.
Webhooks: The Simplest Option
A webhook posts the execution context directly to an HTTP(S) endpoint you control, such as an Azure Function or Logic App, with no separate Azure Service Bus namespace to provision. You register it in PRT with Register New WebHook (Ctrl+W), supplying three required items:
- Name — a unique label for the registration
- Endpoint URL — where the execution context is posted (only port 80 for HTTP or port 443 for HTTPS is supported)
- Authentication — how the endpoint verifies the request is legitimate
Three authentication types are available: HttpHeader (one or more key/value pairs sent as HTTP headers), HttpQueryString (key/value pairs appended to the URL as a query string), and WebhookKey (a single query-string value using the key name code). WebhookKey is specifically called out as the right choice for Azure Functions, because Functions expect their authentication key under that exact query-string name. Registered webhooks are stored in the ServiceEndpoint table with a Contract value of 8, and a step registered against a webhook works just like any plug-in step (message, table, stage, execution mode) with no extra configuration data to supply.
Azure Service Bus: Queue vs. Topic
Service Bus endpoints support several contract types:
| Contract | Listener required? | Delivery model | Notes |
|---|---|---|---|
| Queue | No (messages wait until read) | One consumer per message | Supports destructive reads (message removed once read) and nondestructive reads; messages persist for a finite, configurable duration |
| One-way | Yes, actively listening | Fire-and-forget to a listener | If no listener is active, Dataverse retries with exponentially increasing delays, then marks the job Failed |
| Two-way | Yes | Fire-and-forget, but the listener can return a string value | Lets the destination pass data back into the plug-in that made the call |
| REST | Yes | Same as two-way, over a REST endpoint | Used when the listener is a REST service rather than a Service Bus client |
| Topic | No (subscribers pull independently) | One message, many subscribers | Each subscription can filter which messages it receives, enabling pub/sub fan-out to multiple downstream systems |
A Queue is the right choice for guaranteed, point-to-point delivery to a single downstream consumer — the message waits safely even if nothing is listening at the moment it's sent. A Topic is the right choice when more than one independent system needs to react to the same Dataverse event, since each subscription can apply its own filter to the shared stream of messages. Authentication for Service Bus and Event Hub endpoints uses Shared Access Signatures (SAS), with the claim generated by Dataverse and signed using the AppFabricIssuer certificate configured for the environment; transport is secured with TLS/SSL.
Azure Event Hubs: High-Volume Streaming
Event Hub is a distinct contract type in the same registration flow, but it's built for a different job: ingesting very high volumes of event data (Event Hubs is designed to handle millions of events per second) for streaming analytics, telemetry, or data-lake pipelines rather than transactional request/reply integration. Registering an Event Hub service endpoint only supports SAS authorization, using the connection string obtained when the event hub was created — there's no queue/topic/one-way/two-way distinction to choose because Event Hubs is inherently a one-way, high-throughput publish model.
Choosing the Right Listening Option
When a scenario asks you to recommend how an external system should listen for Dataverse events, work through this decision order:
- One consumer you own, simple HTTP call, minimal setup → Webhook
- One consumer, guaranteed delivery, listener doesn't need to be always-on → Service Bus Queue
- Multiple independent consumers need the same event → Service Bus Topic with per-subscription filters
- High-volume telemetry or analytics ingestion, throughput over acknowledgement → Event Hub
- The plug-in needs a synchronous value returned before continuing → Service Bus Two-way or REST contract
Every one of these destinations is triggered the same way under the hood — through a registered step and IServiceEndpointNotificationService — so the exam-relevant skill isn't memorizing a new API per destination, it's matching the integration shape (single consumer vs. fan-out, request/reply vs. fire-and-forget, transactional vs. high-volume) to the right contract.
A solution needs to notify three independent downstream systems whenever a case is resolved in Dataverse, with each system able to apply its own filter to the incoming messages. Which Service Bus contract type best fits this requirement?
Which webhook authentication option should a developer choose when registering an endpoint that targets an Azure Function, given that Azure Functions expect their key under a specific query-string name?