Receive change notifications through webhooks
A webhook is an HTTP-based user-defined callback API that you can set up in your infrastructure to receive change notifications and events from a service, such as Microsoft Graph. To use webhooks, you need to define a publicly accessible HTTPS-secured endpoint that receives the notifications.
You can create a subscription to the resource for which you want to be notified of changes. While the subscription is valid, Microsoft Graph sends a notification to your endpoint whenever it detects a change in the resource.
The article guides you through the process of implementing your webhook endpoint, subscribing to and managing Microsoft Graph subscriptions, and how to receive change notifications through webhooks.
For details about how to create change notifications, see Microsoft Graph API change notifications.
Considerations for a webhook endpoint
Before you can receive a notification via webhooks, you must create a publicly accessible, HTTPS-secured endpoint that is addressable via URL. If your endpoint isn't publicly accessible, Microsoft Graph doesn't send notifications to your endpoint.
Your endpoint must provide correct, consistent, and timely HTTP responses in order to reliably receive notifications. If an endpoint doesn't respond in a timely manner, the change notification service may begin to drop notifications. Dropped notifications can't be recovered.
Your endpoint must also continue to remain authenticated to Microsoft Graph, either by continually renewing your subscription or by responding to lifecycle notifications.
HTTP codes and retry logic
Once the Microsoft Graph change notifications service receives a 2xx class code from your endpoint, the notification is considered sent. As long as the change notifications service receives any other HTML response (even an error code) within 10 seconds, the service continues to try to deliver the notification for up to 4 hours.
- If you're able to process the notification within a 3-second window, you should return a
200 - OK
status code to Microsoft Graph - If your service may take more than 10 seconds to process the notification, then you may choose to persist the notification in a queue on your endpoint and return
202 - Accepted
status code to Microsoft Graph. - If the notification isn't processed or queued, return a 5xx class code to indicate an error so that Microsoft Graph can retry the notification.
Notifications that fail to deliver are retried at exponential backoff intervals. Missed notifications may take up to 4 hours to resend once your endpoint comes online.
Throttling
For security and performance reasons, Microsoft Graph throttles notifications sent to endpoints that become slow or unresponsive. It may include dropping notifications in a way that they can't be recovered.
An endpoint is marked "slow" once more than 10% of responses take longer than 10 seconds in a 10-minute window.
- Once an endpoint is marked "slow", any new notifications are sent on a 10-second delay.
- An endpoint exits the "slow" state once less than 10% of responses take longer than 10 seconds in a 10-minute window.
An endpoint is marked "drop" once more than 15% of responses take longer than 10 seconds in a 10-minute window.
- Once an endpoint is marked "drop", any new notifications are dropped, for up to 10 minutes
- An endpoint exits the "drop" state once less than 15% of responses take longer than 10 seconds in a 10-minute window.
If your endpoint is unable to meet these performance characteristics, consider using Event Hubs or Event Grid as a target for receiving notifications.
Authentication
When you create your subscription, an access token is sent to your endpoint. This access token is used only to check the validity of your endpoint and has a lifecycle different from that of your change notification subscription. This access token generally expires within 1 hour.
Your endpoint must be prepared to be regularly reauthorized by Microsoft Graph to ensure that Microsoft Graph can continue to deliver notifications to your endpoint.
If an access token expires, notifications aren't delivered. However, it doesn't trigger endpoint throttling behavior and Microsoft Graph continues to retry sending each notification for up to 4 hours. So if the access token is refreshed within 4 hours of expiration, unsent notifications are delivered.
It's recommended that you add lifecycle notifications to your subscription to receive a warning about token expiration so you can reauthorize your endpoint in a timely manner.
When you renew your subscription, your access token is also refreshed.
Firewall configuration
You can configure the firewall that protects your endpoint to allow inbound connections only from Microsoft Graph, reducing further exposure to invalid change notifications. For a complete list of IP addresses used by Microsoft Graph to deliver change notifications, see additional endpoints for Microsoft 365.
Note
The listed IP addresses that are used to deliver change notifications can be updated at any time without notice.
Create a subscription
Important
Multiple steps are required to ensure a secure communication channel is established and maintained between the Microsoft Graph change notifications service and your endpoint.
To start receiving Microsoft Graph change notifications, you must create a subscription using the URL of your endpoint (notification URL) to establish the subscription. The pattern of establishing a subscription is as follows:
The client app sends a subscription request to subscribe to changes on a specific resource.
Microsoft Graph checks the request.
- If the request is valid, Microsoft Graph sends a validation token to the notification URL for the client app to validate the notification URL.
- If the request is invalid, Microsoft Graph sends an error response with an error code and details.
When the client receives the notification URL validation request, the client responds with the validation token in plain text.
Microsoft Graph validates the client's validation token response and if the validation token is valid, responds with a subscription ID.
Subscription request
The client app sends a POST request to the /subscriptions
endpoint. The following example shows a basic request to subscribe to changes to a specific mail folder on behalf of the signed-in user. For more information about other Microsoft Graph resources that support change notifications, see supported resources.
POST https://graph.microsoft.com/v1.0/subscriptions
Content-Type: application/json
{
"changeType": "created,updated",
"notificationUrl": "https://webhook.azurewebsites.net/notificationClient",
"lifecycleNotificationUrl": "https://webhook.azurewebsites.net/api/lifecycleNotifications",
"resource": "/me/mailfolders('inbox')/messages",
"expirationDateTime": "2016-03-20T11:00:00.0000000Z",
"clientState": "SecretClientState"
}
The clientState property is required. Setting it property allows your service to confirm that change notifications you receive originate from Microsoft Graph. For this reason, the value of the property should remain secret and known only to your application and the Microsoft Graph service.
If successful, Microsoft Graph returns a 201 Created
code and a subscription object in the body.
Each subscription has a unique subscriptionId, even if you have multiple subscriptions that monitor the same resource and use the same notification URL.
Note
Any query string parameter included in the notificationUrl property is included in the HTTP POST request when notifications are being delivered to your service.
Duplicate subscriptions are not allowed. When a subscription request contains the same values for changeType and resource as an existing subscription, the request fails with an HTTP error code 409 Conflict
, and the error message Subscription Id <> already exists for the requested combination
.
notificationUrl validation
When you send a request to create a subscription to get change notifications through webhooks, the subscription service checks if the notificationUrl property in your subscription request is valid. The validation process works as follows:
Note
If you're subscribing to lifecycle notifications as well, the subscription service also validates the lifecycleNotificationUrl.
When a subscription is requested, Microsoft Graph encodes a validation token and includes it in a POST request to the notification URL as follows.
Content-Type: text/plain; charset=utf-8 POST https://{notificationUrl}?validationToken={opaqueTokenCreatedByMicrosoftGraph}
The client must properly decode the URL to get the plain text validation token from Microsoft Graph.
Escaping any HTML or JavaScript is a good practice because malicious actors can use the notification endpoint for cross-site scripting type of attacks. Microsoft Graph never sends any value containing HTML or JavaScript code.
In general, treat the validation token value as opaque, as the token format can change without notice.
The client must respond with the following characteristics within 10 seconds of step 1:
- A status code of
HTTP 200 OK
. - A content type of
text/plain
. - A body that includes the URL decoded plain text validation token.
Important
The validation token must be returned in plain text. If the client returns an encoded validation token, the validation fails.
- A status code of
If the endpoint validation fails, Microsoft Graph doesn't create the subscription.
Receive notifications
While the subscription is valid and there are changes to the resource that you subscribed to, Microsoft Graph sends a POST
request to the notificationUrl with details of the changes. This payload is the change notification.
For most subscriptions, Microsoft Graph doesn't delay sending notifications but delivers all notifications within the SLA unless the service is experiencing an incident.
A change notification payload sent to your endpoint can contain a collection of change notifications relating to your subscriptions.
Change notification example
When the user receives an email, Microsoft Graph sends a change notification object to the client app as shown in the following example. See changeNotificationCollection and the related changeNotification for details of the notification payload.
When many changes occur, Microsoft Graph may send multiple notifications that correspond to different subscriptions in the same POST
request.
{
"value": [
{
"id": "lsgTZMr9KwAAA",
"subscriptionId":"{subscription_guid}",
"subscriptionExpirationDateTime":"2016-03-19T22:11:09.952Z",
"clientState":"secretClientValue",
"changeType":"created",
"resource":"users/{user_guid}@{tenant_guid}/messages/{long_id_string}",
"tenantId": "84bd8158-6d4d-4958-8b9f-9d6445542f95",
"resourceData":
{
"@odata.type":"#Microsoft.Graph.Message",
"@odata.id":"Users/{user_guid}@{tenant_guid}/Messages/{long_id_string}",
"@odata.etag":"W/\"CQAAABYAAADkrWGo7bouTKlsgTZMr9KwAAAUWRHf\"",
"id":"{long_id_string}"
}
}
]
}
Processing the change notification
When you receive a change notification:
Validate the clientState property. It must match the value originally submitted with the subscription creation request.
If there's a mismatch, don't consider the change notification as valid. It's possible that the change notification isn't originated from Microsoft Graph and may have been sent by a rogue actor. You should also investigate where the change notification comes from and take appropriate action.
Update your client app based on your business logic.
Subscription lifecycle
When they're no longer needed, subscriptions may be deleted or expire. When you create your subscription, you set an expiration date using the expirationDateTime property. Once this time passes, Microsoft Graph deletes the subscription and doesn't send notifications to your endpoint. You may also explicitly delete your subscription.
The simplest way to continue receiving notifications is to continue renewing your subscription request. Each notification includes a subscriptionExpirationDateTime property. You can use it to guide you when to renew your subscription.
Each subscription also includes an access token granted to the endpoint. The expiration time of this access token may occur before the subscription expiration. You can manage access token expiration using lifecycle notifications for your subscription.
Renew a subscription
PATCH https://graph.microsoft.com/v1.0/subscriptions/{id}
Content-Type: application/json
{
"expirationDateTime": "2016-03-22T11:00:00.0000000Z"
}
If the subscription renewal request is successful, Microsoft Graph returns a 200 OK
response code and a subscription object in the response body. The subscription object includes the new expirationDateTime value.
Delete a subscription
If the client app no longer wants change notifications, it can delete the subscription using its subscriptionId as follows:
DELETE https://graph.microsoft.com/v1.0/subscriptions/{id}
If successful, Microsoft Graph returns a 204 No Content
code.
Lifecycle notifications for your subscription
For increased flexibility and reliability, when you create a subscription, you may also subscribe to the lifecycle notifications for that subscription by providing a lifecycleNotificationUrl endpoint that receives, processes, and responds to lifecycle notifications.
When you subscribe to lifecycle notifications, Microsoft Graph alerts you:
- When the access token is about to expire.
- When a subscription is about to expire.
- When a tenant administrator revokes your app's permissions to read a resource.
Note
If an access token expires, notifications are not delivered to the endpoint. But Microsoft Graph continues to retry sending each notification for up to 4 hours. So if the access token is refreshed within 4 hours of expiration, unsent notifications are delivered.
For more information on how to utilize lifecycle notifications for your subscription, see lifecycle notifications.
Summary
In this article, you learned how to receive change notifications through webhooks.
- Create a subscription by sending a POST request to the
/subscriptions
endpoint. - Microsoft Graph validates the webhook notification endpoint before it completes the subscription creation process. A unique subscriptionID is linked to the subscription.
- As long as the subscription is still valid and changes occur to the subscribed resource, Microsoft Graph sends change notifications to the notificationUrl endpoint.
- Regularly renew the subscription to maintain its validity and continue receiving updates on the subscribed changes.