Working with Webhooks in Dynamics 365 Business Central
Webhooks is the way to get notified if an entity changes in Dynamics 365 Business Central. For general information about webhooks, see Push notifications via webhooks in Microsoft REST API Guidelines.
In the following replace the URL prefix for Dynamics 365 Business Central depending on environment following the guideline.
Register a webhook subscription
Using webhooks requires the client/subscriber to perform a handshake with Dynamics 365 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, Dynamics 365 Business Central will issue 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 Dynamics 365 Business Central receives the response containing the validationToken
, the subscription is registered and webhook notifications will be 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.
Renewing the subscription
Subscriptions will expire after 3 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 cannot 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 is 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",
"systemCreatedAt": "2017-01-23T00:24:31.766Z",
"systemCreatedBy": "f2a5738a-44e3-ea11-bb43-000d3a2feca1",
"systemModifiedAt": "2020-08-21T00:24:31.777Z",
"systemModifiedBy": "f2a5738a-44e3-ea11-bb43-000d3a2feca1"
},
{
"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",
"systemCreatedAt": "2017-01-23T00:24:31.766Z",
"systemCreatedBy": "f2a5738a-44e3-ea11-bb43-000d3a2feca1",
"systemModifiedAt": "2020-08-21T00:24:31.777Z",
"systemModifiedBy": "f2a5738a-44e3-ea11-bb43-000d3a2feca1"
},
{
"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",
"systemCreatedAt": "2017-01-23T00:24:31.766Z",
"systemCreatedBy": "f2a5738a-44e3-ea11-bb43-000d3a2feca1",
"systemModifiedAt": "2020-08-21T00:24:31.777Z",
"systemModifiedBy": "f2a5738a-44e3-ea11-bb43-000d3a2feca1"
}, {
"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",
"systemCreatedAt": "2017-01-23T00:24:31.766Z",
"systemCreatedBy": "f2a5738a-44e3-ea11-bb43-000d3a2feca1",
"systemModifiedAt": "2020-08-21T00:24:31.777Z",
"systemModifiedBy": "f2a5738a-44e3-ea11-bb43-000d3a2feca1"
}
]
}
Created, updated, and deleted identifies the state change for the entity. By collection Dynamics 365 Business Central sends a notification that many records have been created or changed. A filter is applied to the resource, enabling the subscriber to request all entities satisfying the filter.
Notifications are not sent immediately when the record changes. By delaying notifications, Dynamics 365 Business Central can ensure that only one notification is sent, even though the entity might have changed several times within a few seconds.
Note
If Dynamics 365 Business Central cannot reach the subscriber, several retries will be 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 will be attempted and the subscription will be deleted.
Unsubscribing
To remove a subscription, execute a delete request.
Supported entities
To get a list of webhook supported entitites, 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"
}......
]
}
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 will be sent for the header if a change is made a to a line. E.g. a notification to a subscription for salesInvoice will be sent, if a change is made to a related salesInvoiceLine.
Custom APIs are also webhook-enabled and will be listed in webhookSupportedResources if Dynamics 365 Business Central is able to send notifications for the entity.
Note
Webhooks are not 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.
Notes for on-premise
By default, a subscription lives for 3 days if it is not renewed. The value is specified in the CustomSettings.config file under the ApiSubscriptionExpiration entry. There is a maximum number of subscriptions specified in the ApiSubscriptionMaxNumberOfSubscriptions in the CustomSettings.config file.
See also
Subscription Resource Type
Get subscriptions
Create subscriptions
Update subscriptions
Delete subscriptions
Microsoft REST API Guidelines - Push notifications via webhooks