Register a webhook

Use the Plug-in Registration tool to register a webhook. To get the Plug-in registration tool, see Download tools from NuGet.

In the Plug-in Registration tool there is a new Register New Web Hook option to select.

Shows the menu option to register a new web hook. The keyboard shortcut is Ctrl+W

When you register a webhook you must provide three items of information:

Item Description
Name A unique name describing the web hook.
Endpoint URL The URL to post execution context information to.
Authentication One of three authentication options. For any type of authentication, you must provide the keys that will identify the request as legitimate.

Authentication options

The correct webhook registration authentication option and values to use depend on what the endpoint expects. The owner of the endpoint must tell you what to use. To use webhooks with Common Data Service, the endpoint must allow one of the three authentication options described below:

Type Description
HttpHeader Includes one or more key values pairs in the header of the http request.
Example:
Key1: Value1
Key2: Value2
WebhookKey Includes a query string using code as the key and a value required by the endpoint. When registering the web hook using the Plug-in Registration tool, only enter the value.
Example:
?code=00000000-0000-0000-0000-000000000001
HttpQueryString Includes one or more key value pairs as query string parameters.
Example:
?Key1=Value1&Key2=Value2

Note

The WebhookKey option is useful with Azure Functions because the authentication query string is expected to have a key name of code.

Any request to the endpoint configured should fail when the authentication options passed in the request do not match. This is the responsibility of the endpoint.

Query webhook Registrations

Webhook registrations are stored in the ServiceEndpoint Entity and have a Contract value of 8.

You can find details about the registered webhooks by querying the ServiceEndpoint entity.

Web API:

GET [organization URI]/api/data/v9.0/serviceendpoints?$filter=contract eq 8&$select= serviceendpointid,name,authtype,url

More information: Query Data using the Web API

FetchXml:

<fetch>
  <entity name="serviceendpoint" >
    <attribute name="serviceendpointid" />
    <attribute name="name" />
    <attribute name="authtype" />
    <attribute name="url" />
    <filter>
      <condition attribute="contract" operator="eq" value="8" />
    </filter>
  </entity>
</fetch> 

More information: Use FetchXML with FetchExpression

Details about the authentication values set are in the AuthValue property and cannot be retrieved.

Register a step for a webhook

Registering a step for a webhook is like registering a step for a plugin. The main difference is that you cannot specify any configuration information.

Just like a plugin, you specify the message, and information about entities when appropriate. You can also specify where in the event pipeline to execute the web hook, the execution mode and whether to delete any AsyncOperation when the operation succeeds.

Plugin Registration dialog to register a new webhook step

Information about the Step Name, and Description will be auto-populated based on the options you choose, but you can change them. If you do not set some Filtering Attributes for a message that supports them, you will be prompted to do so as a performance best practices.

Execution mode and debugging your web hook registration

Your choice in registering the webhook changes the experience you will have when debugging if things don’t work.

Asynchronous mode

When you use asynchronous execution mode an asyncoperation job will be created to capture the success or failure of the operation. Choosing to delete the asyncoperation when it succeeds will save you database space.

Any errors that occur will be recorded in System Jobs. In the web application you can go to Settings > System > System Jobs to review the status of any web hooks. There will be a Status Reason value of Failed. Open the failed system job entity to find details that describe why the job failed.

Query failed asynchronous jobs for a given step

When you know the sdkmessageprocessingstepid of a given step, you can query the AsynchronousOperations Entity for any errors. You can use the OwningExtensionId value to filter the results to a specific registered step. The following examples use <stepid> for the sdkmessageprocessingstepid of the step.

Tip

To get the sdkmessageprocessingstepid of a given step, see Query steps registered for a webhook below.

Web API:

GET [organization URI]/api/data/v9.0/asyncoperations?$orderby=completedon desc&$filter=statuscode eq 31 and _owningextensionid_value eq @stepid&$select=name,friendlymessage,errorcode,message,completedon?@stepid=<stepid>

More information: Query Data using the Web API

FetchXML:

<fetch>
  <entity name="asyncoperation" >
    <attribute name="name" />
        <attribute name="friendlymessage" />
    <attribute name="errorcode" />
    <attribute name="message" />
    <attribute name="completedon" />     
    <filter>
      <condition attribute="owningextensionid" operator="eq" value="<stepid>" />
    </filter>
    <order attribute="completedon" descending="true" />
  </entity>
</fetch>

More information: Use FetchXML with FetchExpression

Synchronous mode

When you choose to use a synchronous execution mode any failure will be reported back to the user of the application with an Endpoint unavailable error dialog informing the user that the webhook service endpoint may be configured incorrectly or is not available. The dialog will allow you to download a log file to get details on any errors.

Note

You should use synchronous mode when it is important that the operation triggered by the webhook occur immediately or if you want the entire transaction to fail unless the webhook payload is recieved by the service. A simple webhook step registration provides limited options to manage failure, but you can also invoke webhooks using plugins workflow activities if you require more control. More information: Invoke a webhook from a plugin or workflow activity.

Query steps registered for a webhook

Data for registered webhooks is in the SdkMessageProcessingStep Entity.

You can query the steps registered for a specific webhook when you know the serviceendpointid for the webhook. See Query webhook registrations for a query to get the id for a registered web hook.

Web API:

You can use this Web API Query where <id> is the ServiceEndpointId of the webhook:

GET [organization URI]/api/data/v9.0/serviceendpoints(@id)/serviceendpoint_sdkmessageprocessingstep?$select=sdkmessageprocessingstepid,name,description,asyncautodelete,filteringattributes,mode,stage?@id=<id>

For more information about the registered step, you can use this Web API query where <stepid> is the SdkMessageProcessingStepId for the step:

GET [organization URI]/api/data/v9.0/sdkmessageprocessingsteps(@id)?$select=name,description,filteringattributes,asyncautodelete,mode,stage&$expand=plugintypeid($select=friendlyname),eventhandler_serviceendpoint($select=name),sdkmessagefilterid($select=primaryobjecttypecode),sdkmessageid($select=name)?@id=<stepid>

FetchXML:

You can use this FetchXML to get the same information in one query where <serviceendpointid> is the id of the webhook:

<fetch>
  <entity name="sdkmessageprocessingstep" >
    <attribute name="name" />
    <attribute name="filteringattributes" />
    <attribute name="stage" />
    <attribute name="asyncautodeletename" />
    <attribute name="description" />
    <attribute name="mode" />
    <link-entity name="serviceendpoint" from="serviceendpointid" to="eventhandler" link-type="inner" alias="endpnt" >
      <attribute name="name" />
      <filter>
        <condition attribute="serviceendpointid" operator="eq" value="<serviceendpointid>" />
      </filter>
    </link-entity>
    <link-entity name="sdkmessagefilter" from="sdkmessagefilterid" to="sdkmessagefilterid" link-type="inner" alias="fltr" >
      <attribute name="primaryobjecttypecode" />
    </link-entity>
    <link-entity name="sdkmessage" from="sdkmessageid" to="sdkmessageid" link-type="inner" alias="msg" >
      <attribute name="name" />
    </link-entity>
  </entity>
</fetch>

Next steps

Test webhook registration with request logging site
Use webhooks to create external handlers for server events