Working with webhooks in Dynamics 365 Business Central

Webhooks is the way to get notified if an entity changes in Business Central. Learn more about webhooks in Push notifications via webhooks in the Microsoft REST API Guidelines.

In the sections that follow, replace the URL prefix for Business Central depending on the environment by following the guideline.

Important

With Business Central version 19, all webhook notifications sent from Business Central will no longer contain the byte order mark (BOM), to align with RCF 7159, section 8.1.

Register a webhook subscription

Using webhooks requires the client/subscriber to perform a handshake with Business Central to register the webhook subscription.

POST https://{businesscentralPrefix}/api/v2.0/subscriptions 
Content-type: application/json
{
  "notificationUrl": "https://{notificationUrl}",
  "resource": "/api/v2.0/companies(f64eba74-dacd-4854-a584-1834f68cfc3a)/customers",
  "clientState": "optionalValueOf2048"
}

Once the POST is issued against the subscription API to create the subscription, Business Central issues a request to the notificationUrl, passing a validationToken parameter on the query string. Subscriber needs to perform the handshake by returning validationToken in the response body and provide status code 200.

If Business Central receives the response containing the validationToken, the subscription is registered and webhook notifications are sent to the notificationUrl.

Important

Handshake is mandatory when creating a subscription and renewing a subscription. In both cases the client has to return the validationToken in the body with response code 200 OK.

Client state

Optionally clientState can be provided in the POST and PATCH requests bodies. clientState is included in the body of a webhook notification and can be used as an opaque token; a shared secret, enabling the subscriber to verify notifications.

Custom APIs

If you're subscribing to a custom API page, both the URL you send the subscription HTTP request to and the resource path you wish to subscribe to must include the <APIPublisher>, <APIGroup>, and <APIVersion> elements equivalent to: api/<APIPublisher>/<APIGroup>/<APIVersion>/subscriptions. For example, if your API publisher is pub, your API group is grp, and the version is 1.0, part of the URL will contain these elements api/pub/grp/v1.0/subscriptions.

Renewing the subscription

Subscriptions will expire after three days, if not renewed before. Subscriptions are renewed by issuing a PATCH request to the subscription.

PATCH https://{businesscentralPrefix}/api/v2.0/subscriptions({id}) 

PATCH requests a handshake, just like POST requests, meaning that a subscription can't be renewed unless the client returns the validationToken in the body.

Subscription expiration time is listed in expirationDateTime property of the subscription.

Notifications and change types

Valid subscriptions push the notifications on every entity update.

Each notification sent to the subscriber (notificationUrl) can contain multiple notifications from different subscriptions. Here's a sample notification payload:

{
  "value": [
    {
      "subscriptionId": "webhookItemsId",
      "clientState": "someClientState",
      "expirationDateTime": "2018-10-29T07:52:31Z",
      "resource": "api/v2.0/companies(b18aed47-c385-49d2-b954-dbdf8ad71780)/items(26814998-936a-401c-81c1-0e848a64971d)",
      "changeType": "updated",
      "lastModifiedDateTime": "2018-10-26T12:54:20.467Z"
    },
    {
      "subscriptionId": "webhookCustomersId",
      "clientState": "someClientState",
      "expirationDateTime": "2018-10-29T12:50:30Z",
      "resource": "api/v2.0/companies(b18aed47-c385-49d2-b954-dbdf8ad71780)/customers(130bbd17-dbb9-4790-9b12-2b0e9c9d22c3)",
      "changeType": "created",
      "lastModifiedDateTime": "2018-10-26T12:54:26.057Z"
    },
    {
      "subscriptionId": "webhookCustomersId",
      "clientState": "someClientState",
      "expirationDateTime": "2018-10-29T12:50:30Z",
      "resource": "api/v2.0/companies(b18aed47-c385-49d2-b954-dbdf8ad71780)/customers(4b4f31f0-dc1c-4033-b2aa-ab03ca1d6ebc)",
      "changeType": "deleted",
      "lastModifiedDateTime": "2018-10-26T12:54:30.503Z"
    },    
    {
      "subscriptionId": "salesInvoice",
      "clientState": "someClientState",
      "expirationDateTime": "2018-10-20T10:55:01Z",
      "resource": "/api/v2.0/companies(7dbba574-5f69-4167-a43e-fb975045de15)/salesInvoices?$filter=lastDateTimeModified%20gt%202018-10-15T11:00:00Z",
      "changeType": "collection",
       "lastModifiedDateTime": "2018-10-26T12:54:30.503Z"
    }
  ]
}

The "changeType" parameter indicates the change type:

  • created, updated, and deleted identify the state change for the entity.

  • collection means Business Central sends a notification that many records are created or changed. A filter is applied to the resource, enabling the subscriber to request all entities satisfying the filter.

    Notifications aren't sent immediately when the record changes. By delaying notifications, Business Central can ensure that only one notification is sent, even though the entity might have changed several times within a few seconds. By default, the system waits 30 seconds after the first change to an entity before it sends the notification. During the 30-second delay, if more than a 1,000 records are changed, a single collection notification is sent—otherwise, a separate notification is sent for each change. With Business Central on-premises, this time delay and notification limit are configurable.

    Tip

    • You can subscribe to integration event OnGetDelayTime in codeunit API Webhook Notification Mgt. to change the delay time. Keep in mind that the delay time is in millisecconds.
    • You can subscribe to integration event OnGetMaxNumberOfNotifications in codeunit API Webhook Notification Send to change the notification threshold for collection.

Note

If Business Central can't reach the subscriber, several retries are attempted over the next 36 hours. The subscriber must respond with following error codes: 408 - Request Timeout, 429 - Too Many Requests or any error in 500-599 range (5xx). If subscriber responds with any other code than listed, no retries are attempted and the subscription is deleted.

Unsubscribing

To remove a subscription, execute a delete request.

Supported entities

To get a list of webhook supported entities, the following request can be issued. The $filter parameter ensures that only v2.0 APIs are returned. Filter can be removed or changed.

GET https://{businesscentralPrefix}/api/microsoft/runtime/beta/companies({{companyId}})/webhookSupportedResources?$filter=resource eq 'v2.0*' 
Content-type: application/json
{  
  "value": [
  {
      "resource": "v2.0/accounts"
  },
  {
      "resource": "v2.0/companyInformation"
  }......
  ]
}

List of supported entities

  • accounts
  • companyInformation
  • countriesRegions
  • currencies
  • customerPaymentJournals
  • customers
  • dimensions
  • employees
  • generalLedgerEntries
  • itemCategories
  • items
  • journals
  • paymentMethods
  • paymentTerms
  • purchaseInvoices
  • salesCreditMemos
  • salesInvoices
  • salesOrders
  • salesQuotes
  • shipmentMethods
  • unitsOfMeasure
  • vendors

For Document APIs, a notification is sent for the header if a change is made to a line. For example, a notification to a subscription for salesInvoice is sent, if a change is made to a related salesInvoiceLine.

Custom APIs are also webhook-enabled and are listed in webhookSupportedResources if Business Central is able to send notifications for the entity.

Note

Webhooks aren't supported for APIs in the following cases:

  • The source table for the API page is a temporary table (SourceTableTemporary = true).
  • The API page has a composite key (for example, if ODataKeyFields consists of several fields or is missing, then the primary key for the source table consists of several fields).
  • The source table for the API page is a system table ("Table No." > 2000000000).
  • The API is declared through an API type query, for example, and not through an API type page.
  • The source table for the API page is Job Queue Entry ("Table No." = 472).

Note

Changes made by users who aren't able to schedule job queues aren't notified until another user who is able to schedule job queues makes another change to the same table.

Notes for on-premises

The Business Central Server includes several configuration settings in the CustomSettings.config file that control the behavior of webhook subscriptions and notifications. For example:

  • The ApiSubscriptionExpiration setting specifies the life time of a subscription. By default, a subscription lives for three days if it isn't renewed.
  • The ApiSubscriptionMaxNumberOfSubscriptions setting specifies the maximum number of subscriptions that can be created per tenant.
  • The ApiSubscriptionDelayTime setting specifies the amount of time (in milliseconds) that the system waits before processing notifications. The ApiSubscriptionMaxNumberOfNotifications setting specifies the maximum number of notifications that can be delivered per NotificationUrl. Using these two settings, you can control what constitutes a collection notification.

Notes for Power Automate flows

Webhook notifications are used to trigger Power Automate flows from events in Business Central. However, the Business Central connector for Power Automate can't process collection notifications for flows. With Business Central online, this condition means that if an event creates or changes more than 1,000 records within 30 seconds, the associated flow isn't triggered. The same applies to Business Central on-premises although the limits on the records depend on the Business Central Server configuration.

Subscription resource type
Get subscriptions
Create subscriptions
Update subscriptions
Delete subscriptions
Microsoft REST API guidelines - Push notifications via webhooks